This is code used to make plots based on output from the “IndividualPondModels_Forecasts85” for boththe CR and YF Read in the output files for each pond/RCP combination then work on delta figures and figures like Hamlet et al. 2020

rm(list = ls())

library(tidyverse)
library(dplyr)
library(rjags)
library(ggplot2)

set.seed(1)

Starting with the Yakutat Forelands

RCP 45

Reading in the data

Mod_YF45 <- read.csv("Mod_YF45.csv", header = T)

2012-2020

# List of unique pond names from the dataframe
pond_names <- unique(Mod_YF45$pond_name)

# Initialize an empty dataframe to store results
avgMed_2020 <- data.frame(Pond = pond_names, AvgMed_2020 = numeric(length(pond_names)))

# Loop through each pond name
for (i in seq_along(pond_names)) {
  pond_name <- pond_names[i]
  
  # Filter data for the current pond and for dates before January 1, 2021
  filtered_data <- Mod_YF45 %>%
    filter(pond_name == !!pond_name, as.Date(time) < as.Date("2021-01-01"))
  
  # Calculate the mean of 'med' (which corresponds to X50%)
  avg_med <- mean(filtered_data$med, na.rm = TRUE)
  
  # Store the result in the dataframe
  avgMed_2020[i, "AvgMed_2020"] <- avg_med
}

# Print the dataframe
print(avgMed_2020)

2030-2039

library(lubridate)
library(dplyr)
library(tidyr)
library(ggplot2)

# List of unique pond names from the dataframe
pond_names <- unique(Mod_YF45$pond_name)

# Initialize a dataframe to store results with years as columns
avgMed_2030 <- data.frame(Pond = pond_names)

# Loop through each year from 2030 to 2039
for (yr in 2030:2039) {
  # Calculate average medians for each year and store as a new column
  avgMed_col <- sapply(pond_names, function(pond_name) {
    yearly_data <- Mod_YF45 %>%
      filter(pond_name == !!pond_name, year(as.Date(time)) == yr)
    
    avg_med <- mean(yearly_data$med, na.rm = TRUE)
    return(avg_med)
  })
  
  # Add the results as a new column to the dataframe
  avgMed_2030[[as.character(yr)]] <- avgMed_col
}

# Print the final dataframe
print(avgMed_2030)

# Convert to long format for ggplot2
avgMed_2030_long <- avgMed_2030 %>%
  pivot_longer(cols = -Pond, names_to = "Year", values_to = "AvgMed")

# Plot the data
ggplot(avgMed_2030_long, aes(x = Year, y = AvgMed, color = Pond, group = Pond)) +
  geom_line() +
  geom_point() +
  labs(title = "Average Median per Pond from 2030 to 2039",
       x = "Year",
       y = "Average Median") +
  theme_minimal()

2060-2069

library(lubridate)
library(dplyr)
library(tidyr)
library(ggplot2)

# List of unique pond names from the dataframe
pond_names <- unique(Mod_YF45$pond_name)

# Initialize a dataframe to store results with years as columns
avgMed_2060 <- data.frame(Pond = pond_names)

# Loop through each year from 2060 to 2069
for (yr in 2060:2069) {
  # Calculate average medians for each year and store as a new column
  avgMed_col <- sapply(pond_names, function(pond_name) {
    yearly_data <- Mod_YF45 %>%
      filter(pond_name == !!pond_name, year(as.Date(time)) == yr)
    
    avg_med <- mean(yearly_data$med, na.rm = TRUE)
    return(avg_med)
  })
  
  # Add the results as a new column to the dataframe
  avgMed_2060[[as.character(yr)]] <- avgMed_col
}

# Print the final dataframe
print(avgMed_2060)

# Convert to long format for ggplot2
avgMed_2060_long <- avgMed_2060 %>%
  pivot_longer(cols = -Pond, names_to = "Year", values_to = "AvgMed")

# Plot the data
ggplot(avgMed_2060_long, aes(x = Year, y = AvgMed, color = Pond, group = Pond)) +
  geom_line() +
  geom_point() +
  labs(title = "Average Median per Pond from 2060 to 2069",
       x = "Year",
       y = "Average Median") +
  theme_minimal()

2090-2099

library(lubridate)
library(dplyr)
library(tidyr)
library(ggplot2)

# List of unique pond names from the dataframe
pond_names <- unique(Mod_YF45$pond_name)

# Initialize a dataframe to store results with years as columns
avgMed_2090 <- data.frame(Pond = pond_names)

# Loop through each year from 2090 to 2099
for (yr in 2090:2099) {
  # Calculate average medians for each year and store as a new column
  avgMed_col <- sapply(pond_names, function(pond_name) {
    yearly_data <- Mod_YF45 %>%
      filter(pond_name == !!pond_name, year(as.Date(time)) == yr)
    
    avg_med <- mean(yearly_data$med, na.rm = TRUE)
    return(avg_med)
  })
  
  # Add the results as a new column to the dataframe
  avgMed_2090[[as.character(yr)]] <- avgMed_col
}

# Print the final dataframe
print(avgMed_2090)

# Convert to long format for ggplot2
avgMed_2090_long <- avgMed_2090 %>%
  pivot_longer(cols = -Pond, names_to = "Year", values_to = "AvgMed")

# Plot the data
ggplot(avgMed_2090_long, aes(x = Year, y = AvgMed, color = Pond, group = Pond)) +
  geom_line() +
  geom_point() +
  labs(title = "Average Median per Pond from 2090 to 2099",
       x = "Year",
       y = "Average Median") +
  theme_minimal()

# Rename columns to reflect only the years
avgMed_2020 <- avgMed_2020 %>%
  rename(AvgMed_2020 = AvgMed_2020)

avgMed_2030 <- avgMed_2030 %>%
  rename(`2030` = `2030`)

avgMed_2060 <- avgMed_2060 %>%
  rename(`2060` = `2060`)

avgMed_2090 <- avgMed_2090 %>%
  rename(`2090` = `2090`)

# Combine the data frames
combined_avgMed <- avgMed_2020 %>%
  left_join(avgMed_2030, by = "Pond") %>%
  left_join(avgMed_2060, by = "Pond") %>%
  left_join(avgMed_2090, by = "Pond")

# Print the final dataframe
print(combined_avgMed)

# Convert to long format for ggplot2, excluding AvgMed_2020
avgMed_long <- combined_avgMed %>%
  pivot_longer(cols = -Pond, names_to = "Year", values_to = "AvgMed") %>%
  filter(Year %in% as.character(2021:2199))

# Plot the data
ggplot(avgMed_long, aes(x = Year, y = AvgMed, color = Pond, group = Pond)) +
  geom_line() +
  geom_point() +
  labs(title = "Average Median per Pond in the YF - RCP 4.5",
       x = "Year",
       y = "Average Median") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1),# Rotate x-axis labels by 45 degrees
        plot.title = element_text(hjust = 0.5))  

Calcuate the differences here as new columns in the dataframe

library(dplyr)

# Assuming combined_avgMed is loaded and structure verified
Delta_combined_avgMed <- combined_avgMed  # Use your actual dataframe

# Columns to calculate differences for
years <- c("2030", "2031", "2032", "2033", "2034", 
           "2035", "2036", "2037", "2038", "2039", 
           "2060", "2061", "2062", "2063", "2064", 
           "2065", "2066", "2067", "2068", "2069", 
           "2090", "2091", "2092", "2093", "2094", 
           "2095", "2096", "2097", "2098", "2099")

# Loop through each year and calculate the difference
for (year in years) {
  # Create a new column for the difference
  diff_col_name <- paste0("diff_", year)
  Delta_combined_avgMed[[diff_col_name]] <- Delta_combined_avgMed[[year]] - Delta_combined_avgMed$`AvgMed_2020`
}

# Display the structure of Delta_combined_avgMed to verify
str(Delta_combined_avgMed)
'data.frame':   11 obs. of  62 variables:
 $ Pond       : chr  "MP1" "UBP3" "UBP4" "MP3" ...
 $ AvgMed_2020: num  7.32 7 7.75 5.34 6.63 ...
 $ 2030       : num  8.92 8.6 9.35 6.91 8.22 ...
 $ 2031       : num  8.91 8.6 9.37 6.93 8.23 ...
 $ 2032       : num  10.29 9.99 10.72 8.28 9.6 ...
 $ 2033       : num  9.44 9.11 9.86 7.43 8.74 ...
 $ 2034       : num  9.37 9.06 9.8 7.37 8.66 ...
 $ 2035       : num  6.4 6.08 6.83 4.39 5.7 ...
 $ 2036       : num  7.81 7.5 8.27 5.8 7.11 ...
 $ 2037       : num  9.91 9.59 10.34 7.91 9.22 ...
 $ 2038       : num  8.83 8.51 9.26 6.83 8.14 ...
 $ 2039       : num  9.94 9.62 10.38 7.95 9.26 ...
 $ 2060       : num  10.58 10.28 11.04 8.59 9.9 ...
 $ 2061       : num  10.53 10.22 10.97 8.53 9.84 ...
 $ 2062       : num  10.82 10.5 11.27 8.83 10.13 ...
 $ 2063       : num  11.75 11.42 12.19 9.75 11.06 ...
 $ 2064       : num  9.94 9.6 10.38 7.93 9.24 ...
 $ 2065       : num  11.25 10.92 11.68 9.25 10.55 ...
 $ 2066       : num  10.36 10.02 10.8 8.34 9.64 ...
 $ 2067       : num  9.79 9.45 10.22 7.78 9.08 ...
 $ 2068       : num  10.55 10.23 10.99 8.55 9.86 ...
 $ 2069       : num  11.15 10.83 11.59 9.14 10.47 ...
 $ 2090       : num  11.08 10.75 11.5 9.06 10.37 ...
 $ 2091       : num  11.88 11.55 12.31 9.86 11.17 ...
 $ 2092       : num  13.2 12.9 13.6 11.2 12.5 ...
 $ 2093       : num  11.31 11 11.75 9.31 10.62 ...
 $ 2094       : num  11.69 11.38 12.13 9.69 11 ...
 $ 2095       : num  12 11.7 12.5 10 11.3 ...
 $ 2096       : num  12.2 11.8 12.6 10.2 11.5 ...
 $ 2097       : num  11.34 11.02 11.76 9.33 10.64 ...
 $ 2098       : num  11.12 10.8 11.54 9.11 10.43 ...
 $ 2099       : num  12.4 12 12.8 10.4 11.7 ...
 $ diff_2030  : num  1.6 1.6 1.6 1.58 1.59 ...
 $ diff_2031  : num  1.6 1.6 1.61 1.59 1.6 ...
 $ diff_2032  : num  2.98 2.99 2.97 2.95 2.97 ...
 $ diff_2033  : num  2.12 2.11 2.11 2.1 2.11 ...
 $ diff_2034  : num  2.05 2.06 2.05 2.04 2.03 ...
 $ diff_2035  : num  -0.916 -0.915 -0.925 -0.95 -0.927 ...
 $ diff_2036  : num  0.495 0.501 0.519 0.468 0.476 ...
 $ diff_2037  : num  2.59 2.59 2.59 2.57 2.59 ...
 $ diff_2038  : num  1.52 1.51 1.51 1.5 1.51 ...
 $ diff_2039  : num  2.62 2.62 2.63 2.61 2.63 ...
 $ diff_2060  : num  3.26 3.28 3.28 3.25 3.27 ...
 $ diff_2061  : num  3.21 3.22 3.22 3.19 3.21 ...
 $ diff_2062  : num  3.5 3.5 3.52 3.49 3.5 ...
 $ diff_2063  : num  4.44 4.42 4.43 4.42 4.43 ...
 $ diff_2064  : num  2.63 2.61 2.62 2.59 2.61 ...
 $ diff_2065  : num  3.94 3.92 3.93 3.91 3.92 ...
 $ diff_2066  : num  3.04 3.02 3.05 3 3.01 ...
 $ diff_2067  : num  2.47 2.45 2.47 2.45 2.45 ...
 $ diff_2068  : num  3.24 3.23 3.24 3.21 3.23 ...
 $ diff_2069  : num  3.83 3.83 3.83 3.81 3.84 ...
 $ diff_2090  : num  3.76 3.75 3.75 3.72 3.74 ...
 $ diff_2091  : num  4.57 4.55 4.56 4.53 4.54 ...
 $ diff_2092  : num  5.87 5.87 5.88 5.84 5.86 ...
 $ diff_2093  : num  3.99 4 4 3.98 3.99 ...
 $ diff_2094  : num  4.38 4.38 4.38 4.35 4.37 ...
 $ diff_2095  : num  4.73 4.72 4.72 4.69 4.71 ...
 $ diff_2096  : num  4.84 4.84 4.83 4.83 4.83 ...
 $ diff_2097  : num  4.02 4.02 4.01 3.99 4.01 ...
 $ diff_2098  : num  3.81 3.8 3.79 3.77 3.8 ...
 $ diff_2099  : num  5.06 5.03 5.03 5.02 5.04 ...
# Create a new dataframe with the calculated means and standard deviations
Delta_YF45 <- Delta_combined_avgMed %>%
  mutate(
    Mean_2030_2039 = rowMeans(select(., starts_with("diff_203")), na.rm = TRUE),  # Calculate row-wise mean for columns starting with "diff_203"
    SD_2030_2039 = rowSds(as.matrix(select(., starts_with("diff_203"))), na.rm = TRUE),  # Calculate row-wise SD for columns starting with "diff_203"
    Mean_2060_2069 = rowMeans(select(., starts_with("diff_206")), na.rm = TRUE),  # Calculate row-wise mean for columns starting with "diff_206"
    SD_2060_2069 = rowSds(as.matrix(select(., starts_with("diff_206"))), na.rm = TRUE),  # Calculate row-wise SD for columns starting with "diff_206"
    Mean_2090_2099 = rowMeans(select(., starts_with("diff_209")), na.rm = TRUE),  # Calculate row-wise mean for columns starting with "diff_209"
    SD_2090_2099 = rowSds(as.matrix(select(., starts_with("diff_209"))), na.rm = TRUE)  # Calculate row-wise SD for columns starting with "diff_209"
  )

# Print the structure of the new dataframe
str(Delta_YF45)
'data.frame':   11 obs. of  68 variables:
 $ Pond          : chr  "MP1" "UBP3" "UBP4" "MP3" ...
 $ AvgMed_2020   : num  7.32 7 7.75 5.34 6.63 ...
 $ 2030          : num  8.92 8.6 9.35 6.91 8.22 ...
 $ 2031          : num  8.91 8.6 9.37 6.93 8.23 ...
 $ 2032          : num  10.29 9.99 10.72 8.28 9.6 ...
 $ 2033          : num  9.44 9.11 9.86 7.43 8.74 ...
 $ 2034          : num  9.37 9.06 9.8 7.37 8.66 ...
 $ 2035          : num  6.4 6.08 6.83 4.39 5.7 ...
 $ 2036          : num  7.81 7.5 8.27 5.8 7.11 ...
 $ 2037          : num  9.91 9.59 10.34 7.91 9.22 ...
 $ 2038          : num  8.83 8.51 9.26 6.83 8.14 ...
 $ 2039          : num  9.94 9.62 10.38 7.95 9.26 ...
 $ 2060          : num  10.58 10.28 11.04 8.59 9.9 ...
 $ 2061          : num  10.53 10.22 10.97 8.53 9.84 ...
 $ 2062          : num  10.82 10.5 11.27 8.83 10.13 ...
 $ 2063          : num  11.75 11.42 12.19 9.75 11.06 ...
 $ 2064          : num  9.94 9.6 10.38 7.93 9.24 ...
 $ 2065          : num  11.25 10.92 11.68 9.25 10.55 ...
 $ 2066          : num  10.36 10.02 10.8 8.34 9.64 ...
 $ 2067          : num  9.79 9.45 10.22 7.78 9.08 ...
 $ 2068          : num  10.55 10.23 10.99 8.55 9.86 ...
 $ 2069          : num  11.15 10.83 11.59 9.14 10.47 ...
 $ 2090          : num  11.08 10.75 11.5 9.06 10.37 ...
 $ 2091          : num  11.88 11.55 12.31 9.86 11.17 ...
 $ 2092          : num  13.2 12.9 13.6 11.2 12.5 ...
 $ 2093          : num  11.31 11 11.75 9.31 10.62 ...
 $ 2094          : num  11.69 11.38 12.13 9.69 11 ...
 $ 2095          : num  12 11.7 12.5 10 11.3 ...
 $ 2096          : num  12.2 11.8 12.6 10.2 11.5 ...
 $ 2097          : num  11.34 11.02 11.76 9.33 10.64 ...
 $ 2098          : num  11.12 10.8 11.54 9.11 10.43 ...
 $ 2099          : num  12.4 12 12.8 10.4 11.7 ...
 $ diff_2030     : num  1.6 1.6 1.6 1.58 1.59 ...
 $ diff_2031     : num  1.6 1.6 1.61 1.59 1.6 ...
 $ diff_2032     : num  2.98 2.99 2.97 2.95 2.97 ...
 $ diff_2033     : num  2.12 2.11 2.11 2.1 2.11 ...
 $ diff_2034     : num  2.05 2.06 2.05 2.04 2.03 ...
 $ diff_2035     : num  -0.916 -0.915 -0.925 -0.95 -0.927 ...
 $ diff_2036     : num  0.495 0.501 0.519 0.468 0.476 ...
 $ diff_2037     : num  2.59 2.59 2.59 2.57 2.59 ...
 $ diff_2038     : num  1.52 1.51 1.51 1.5 1.51 ...
 $ diff_2039     : num  2.62 2.62 2.63 2.61 2.63 ...
 $ diff_2060     : num  3.26 3.28 3.28 3.25 3.27 ...
 $ diff_2061     : num  3.21 3.22 3.22 3.19 3.21 ...
 $ diff_2062     : num  3.5 3.5 3.52 3.49 3.5 ...
 $ diff_2063     : num  4.44 4.42 4.43 4.42 4.43 ...
 $ diff_2064     : num  2.63 2.61 2.62 2.59 2.61 ...
 $ diff_2065     : num  3.94 3.92 3.93 3.91 3.92 ...
 $ diff_2066     : num  3.04 3.02 3.05 3 3.01 ...
 $ diff_2067     : num  2.47 2.45 2.47 2.45 2.45 ...
 $ diff_2068     : num  3.24 3.23 3.24 3.21 3.23 ...
 $ diff_2069     : num  3.83 3.83 3.83 3.81 3.84 ...
 $ diff_2090     : num  3.76 3.75 3.75 3.72 3.74 ...
 $ diff_2091     : num  4.57 4.55 4.56 4.53 4.54 ...
 $ diff_2092     : num  5.87 5.87 5.88 5.84 5.86 ...
 $ diff_2093     : num  3.99 4 4 3.98 3.99 ...
 $ diff_2094     : num  4.38 4.38 4.38 4.35 4.37 ...
 $ diff_2095     : num  4.73 4.72 4.72 4.69 4.71 ...
 $ diff_2096     : num  4.84 4.84 4.83 4.83 4.83 ...
 $ diff_2097     : num  4.02 4.02 4.01 3.99 4.01 ...
 $ diff_2098     : num  3.81 3.8 3.79 3.77 3.8 ...
 $ diff_2099     : num  5.06 5.03 5.03 5.02 5.04 ...
 $ Mean_2030_2039: num  1.66 1.67 1.67 1.64 1.66 ...
 $ SD_2030_2039  : num  1.15 1.15 1.15 1.15 1.15 ...
 $ Mean_2060_2069: num  3.36 3.35 3.36 3.33 3.35 ...
 $ SD_2060_2069  : num  0.597 0.599 0.597 0.6 0.603 ...
 $ Mean_2090_2099: num  4.5 4.5 4.49 4.47 4.49 ...
 $ SD_2090_2099  : num  0.657 0.655 0.659 0.657 0.659 ...
# Optionally, view the first few rows to check the new columns
head(Delta_YF45)

Put these into total mean/standard deviations

# Load necessary libraries
library(dplyr)

# Select and rename columns from Delta_YF45
YF45_decadal <- Delta_YF45 %>%
  select(Pond, starts_with("Mean_"), starts_with("SD_"))

# Rename columns without the 'Y' prefix for means
names(YF45_decadal) <- sub("^Mean_", "Mean_", names(YF45_decadal))

# Rename columns without the 'Y' prefix for standard deviations
names(YF45_decadal) <- sub("^SD_", "SD_", names(YF45_decadal))

# Print the structure of the updated dataframe
str(YF45_decadal)
'data.frame':   11 obs. of  7 variables:
 $ Pond          : chr  "MP1" "UBP3" "UBP4" "MP3" ...
 $ Mean_2030_2039: num  1.66 1.67 1.67 1.64 1.66 ...
 $ Mean_2060_2069: num  3.36 3.35 3.36 3.33 3.35 ...
 $ Mean_2090_2099: num  4.5 4.5 4.49 4.47 4.49 ...
 $ SD_2030_2039  : num  1.15 1.15 1.15 1.15 1.15 ...
 $ SD_2060_2069  : num  0.597 0.599 0.597 0.6 0.603 ...
 $ SD_2090_2099  : num  0.657 0.655 0.659 0.657 0.659 ...
# Optionally, view the first few rows to check the new columns
head(YF45_decadal)

Making the plots of these deltas

# Load required packages
library(ggplot2)
library(gridExtra)
library(ggpubr)

# Create a grouped bar plot with error bars for Mean 2030
plot_2030 <- ggplot(YF45_decadal, aes(x = Pond, y = Mean_2030_2039)) +
  geom_bar(stat = "identity", fill = "#FFD92F", color = "black") +
  geom_errorbar(aes(ymin = Mean_2030_2039 - SD_2030_2039, ymax = Mean_2030_2039 + SD_2030_2039),
                width = 0.4,  # Adjust the width of error bars as needed
                position = position_dodge(width = 0.9)) +
  labs(x = "", y = "Delta Temp (C)") +
  ylim(-1, 5) +
  theme_classic() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  theme(plot.title = element_text(hjust = 0.5))  # Centered title
plot_2030


# Create a grouped bar plot with error bars for Mean 2060
plot_2060 <- ggplot(YF45_decadal, aes(x = Pond, y = Mean_2060_2069)) +
  geom_bar(stat = "identity", fill = "#F46D43", color = "black") +
  geom_errorbar(aes(ymin = Mean_2060_2069 - SD_2060_2069, ymax = Mean_2060_2069 + SD_2060_2069),
                width = 0.4,  # Adjust the width of error bars as needed
                position = position_dodge(width = 0.9)) +
  labs(x = "", y = "") +  # No y-axis label
  ylim(-1, 5) +
  theme_classic() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  theme(plot.title = element_text(hjust = 0.5)) +  # Centered title 
  theme(axis.text.y = element_blank(),  # Remove Y-axis tick mark labels
        axis.ticks.y = element_blank())   # Remove Y-axis ticks
plot_2060


# Create a grouped bar plot with error bars for Mean 2090
plot_2090 <- ggplot(YF45_decadal, aes(x = Pond, y = Mean_2090_2099)) +
  geom_bar(stat = "identity", fill = "#D73027", color = "black") +
  geom_errorbar(aes(ymin = Mean_2090_2099 - SD_2090_2099, ymax = Mean_2090_2099 + SD_2090_2099),
                width = 0.4,  # Adjust the width of error bars as needed
                position = position_dodge(width = 0.9)) +
  labs(x = "", y = "") +  # No y-axis label
  ylim(-1, 5) +
  theme_classic() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  theme(plot.title = element_text(hjust = 0.5)) +  # Centered title 
  theme(axis.text.y = element_blank(),  # Remove Y-axis tick mark labels
        axis.ticks.y = element_blank())   # Remove Y-axis ticks
plot_2090

# Combine plots into a panel plot
Delta_YF45_plot <- ggarrange(plot_2030, plot_2060, plot_2090, ncol = 3)

# Save the combined plot
ggsave("Corr_DeltaYF45.png", plot = Delta_YF45_plot, width = 8, height = 3)

Statistical tests for each of these ponds for 2030s, 2060s, and 2090s

2030s

Delta_YF45

# Load required libraries
library(dplyr)
library(broom)
library(tidyr)

# Step 1: Prepare the data
data_long <- Delta_YF45 %>%
  select(Pond, matches("^diff_203[0-9]$")) %>%
  pivot_longer(cols = -Pond, names_to = "Year", values_to = "Difference")

boxplot(data_long$Difference ~ data_long$Pond)


# Step 2: Conduct ANOVA by grouping by Pond
res_YF45 <- aov(Difference ~ Pond, data = data_long)
summary(res_YF45)
            Df Sum Sq Mean Sq F value Pr(>F)
Pond        10    0.0  0.0004       0      1
Residuals   99  131.4  1.3277               
# Step 3: Tukey HSD
post_test_YF45 <- TukeyHSD(res_YF45)
post_test_YF45
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = Difference ~ Pond, data = data_long)

$Pond
                   diff       lwr      upr p adj
MP3-MP1   -0.0199259313 -1.717985 1.678133     1
MP5-MP1   -0.0060886579 -1.704148 1.691971     1
MP8-MP1   -0.0003983733 -1.698458 1.697661     1
PL1-MP1   -0.0044755184 -1.702535 1.693584     1
PL2-MP1   -0.0035107990 -1.701570 1.694549     1
PL3-MP1   -0.0015320097 -1.699591 1.696527     1
UBP1-MP1  -0.0073105687 -1.705370 1.690749     1
UBP2-MP1  -0.0022264448 -1.700286 1.695833     1
UBP3-MP1   0.0018649112 -1.696194 1.699924     1
UBP4-MP1   0.0024935697 -1.695566 1.700553     1
MP5-MP3    0.0138372734 -1.684222 1.711897     1
MP8-MP3    0.0195275580 -1.678532 1.717587     1
PL1-MP3    0.0154504129 -1.682609 1.713510     1
PL2-MP3    0.0164151322 -1.681644 1.714474     1
PL3-MP3    0.0183939216 -1.679665 1.716453     1
UBP1-MP3   0.0126153626 -1.685444 1.710675     1
UBP2-MP3   0.0176994865 -1.680360 1.715759     1
UBP3-MP3   0.0217908425 -1.676268 1.719850     1
UBP4-MP3   0.0224195009 -1.675640 1.720479     1
MP8-MP5    0.0056902847 -1.692369 1.703750     1
PL1-MP5    0.0016131396 -1.696446 1.699672     1
PL2-MP5    0.0025778589 -1.695481 1.700637     1
PL3-MP5    0.0045566482 -1.693503 1.702616     1
UBP1-MP5  -0.0012219107 -1.699281 1.696837     1
UBP2-MP5   0.0038622131 -1.694197 1.701922     1
UBP3-MP5   0.0079535691 -1.690106 1.706013     1
UBP4-MP5   0.0085822276 -1.689477 1.706642     1
PL1-MP8   -0.0040771451 -1.702136 1.693982     1
PL2-MP8   -0.0031124258 -1.701172 1.694947     1
PL3-MP8   -0.0011336365 -1.699193 1.696926     1
UBP1-MP8  -0.0069121954 -1.704972 1.691147     1
UBP2-MP8  -0.0018280715 -1.699887 1.696231     1
UBP3-MP8   0.0022632845 -1.695796 1.700323     1
UBP4-MP8   0.0028919429 -1.695167 1.700951     1
PL2-PL1    0.0009647193 -1.697095 1.699024     1
PL3-PL1    0.0029435086 -1.695116 1.701003     1
UBP1-PL1  -0.0028350503 -1.700894 1.695224     1
UBP2-PL1   0.0022490736 -1.695810 1.700308     1
UBP3-PL1   0.0063404296 -1.691719 1.704400     1
UBP4-PL1   0.0069690880 -1.691090 1.705028     1
PL3-PL2    0.0019787893 -1.696081 1.700038     1
UBP1-PL2  -0.0037997696 -1.701859 1.694260     1
UBP2-PL2   0.0012843542 -1.696775 1.699344     1
UBP3-PL2   0.0053757103 -1.692684 1.703435     1
UBP4-PL2   0.0060043687 -1.692055 1.704064     1
UBP1-PL3  -0.0057785589 -1.703838 1.692281     1
UBP2-PL3  -0.0006944351 -1.698754 1.697365     1
UBP3-PL3   0.0033969209 -1.694662 1.701456     1
UBP4-PL3   0.0040255794 -1.694034 1.702085     1
UBP2-UBP1  0.0050841239 -1.692975 1.703143     1
UBP3-UBP1  0.0091754799 -1.688884 1.707235     1
UBP4-UBP1  0.0098041383 -1.688255 1.707863     1
UBP3-UBP2  0.0040913560 -1.693968 1.702151     1
UBP4-UBP2  0.0047200145 -1.693339 1.702779     1
UBP4-UBP3  0.0006286584 -1.697431 1.698688     1

2060s

Delta_YF45

# Load required libraries
library(dplyr)
library(broom)

# Step 1: Prepare the data
data_long <- Delta_YF45 %>%
  select(Pond, matches("^diff_206[0-9]$")) %>%
  pivot_longer(cols = -Pond, names_to = "Year", values_to = "Difference")

boxplot(data_long$Difference ~ data_long$Pond)


# Step 2: Conduct ANOVA by grouping by Pond
res_YF45 <- aov(Difference ~ Pond, data = data_long)
summary(res_YF45)
            Df Sum Sq Mean Sq F value Pr(>F)
Pond        10   0.00  0.0005   0.001      1
Residuals   99  35.62  0.3598               
# Step 3: Tukey HSD
post_test_YF45 <- TukeyHSD(res_YF45)
post_test_YF45
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = Difference ~ Pond, data = data_long)

$Pond
                   diff        lwr       upr p adj
MP3-MP1   -2.344244e-02 -0.9074241 0.8605392     1
MP5-MP1   -8.398654e-03 -0.8923803 0.8755830     1
MP8-MP1   -7.319974e-03 -0.8913016 0.8766617     1
PL1-MP1   -1.100308e-02 -0.8949847 0.8729785     1
PL2-MP1   -9.354063e-03 -0.8933357 0.8746276     1
PL3-MP1   -7.225049e-03 -0.8912067 0.8767566     1
UBP1-MP1  -1.315030e-02 -0.8971319 0.8708313     1
UBP2-MP1  -1.030475e-02 -0.8942864 0.8736769     1
UBP3-MP1  -7.404233e-03 -0.8913859 0.8765774     1
UBP4-MP1   3.946664e-03 -0.8800350 0.8879283     1
MP5-MP3    1.504379e-02 -0.8689378 0.8990254     1
MP8-MP3    1.612247e-02 -0.8678592 0.9001041     1
PL1-MP3    1.243936e-02 -0.8715423 0.8964210     1
PL2-MP3    1.408838e-02 -0.8698932 0.8980700     1
PL3-MP3    1.621739e-02 -0.8677642 0.9001990     1
UBP1-MP3   1.029214e-02 -0.8736895 0.8942738     1
UBP2-MP3   1.313769e-02 -0.8708439 0.8971193     1
UBP3-MP3   1.603821e-02 -0.8679434 0.9000198     1
UBP4-MP3   2.738910e-02 -0.8565925 0.9113707     1
MP8-MP5    1.078681e-03 -0.8829029 0.8850603     1
PL1-MP5   -2.604427e-03 -0.8865861 0.8813772     1
PL2-MP5   -9.554088e-04 -0.8849370 0.8830262     1
PL3-MP5    1.173605e-03 -0.8828080 0.8851552     1
UBP1-MP5  -4.751649e-03 -0.8887333 0.8792300     1
UBP2-MP5  -1.906092e-03 -0.8858877 0.8820755     1
UBP3-MP5   9.944212e-04 -0.8829872 0.8849760     1
UBP4-MP5   1.234532e-02 -0.8716363 0.8963269     1
PL1-MP8   -3.683107e-03 -0.8876647 0.8802985     1
PL2-MP8   -2.034089e-03 -0.8860157 0.8819475     1
PL3-MP8    9.492432e-05 -0.8838867 0.8840765     1
UBP1-MP8  -5.830329e-03 -0.8898120 0.8781513     1
UBP2-MP8  -2.984773e-03 -0.8869664 0.8809969     1
UBP3-MP8  -8.425938e-05 -0.8840659 0.8838974     1
UBP4-MP8   1.126664e-02 -0.8727150 0.8952483     1
PL2-PL1    1.649018e-03 -0.8823326 0.8856306     1
PL3-PL1    3.778031e-03 -0.8802036 0.8877597     1
UBP1-PL1  -2.147222e-03 -0.8861288 0.8818344     1
UBP2-PL1   6.983343e-04 -0.8832833 0.8846800     1
UBP3-PL1   3.598848e-03 -0.8803828 0.8875805     1
UBP4-PL1   1.494974e-02 -0.8690319 0.8989314     1
PL3-PL2    2.129014e-03 -0.8818526 0.8861106     1
UBP1-PL2  -3.796240e-03 -0.8877779 0.8801854     1
UBP2-PL2  -9.506835e-04 -0.8849323 0.8830309     1
UBP3-PL2   1.949830e-03 -0.8820318 0.8859315     1
UBP4-PL2   1.330073e-02 -0.8706809 0.8972824     1
UBP1-PL3  -5.925254e-03 -0.8899069 0.8780564     1
UBP2-PL3  -3.079697e-03 -0.8870613 0.8809019     1
UBP3-PL3  -1.791837e-04 -0.8841608 0.8838024     1
UBP4-PL3   1.117171e-02 -0.8728099 0.8951533     1
UBP2-UBP1  2.845557e-03 -0.8811361 0.8868272     1
UBP3-UBP1  5.746070e-03 -0.8782356 0.8897277     1
UBP4-UBP1  1.709697e-02 -0.8668847 0.9010786     1
UBP3-UBP2  2.900513e-03 -0.8810811 0.8868821     1
UBP4-UBP2  1.425141e-02 -0.8697302 0.8982330     1
UBP4-UBP3  1.135090e-02 -0.8726307 0.8953325     1

2090s

Delta_YF45

# Load required libraries
library(dplyr)
library(broom)

# Step 1: Prepare the data
data_long <- Delta_YF45 %>%
  select(Pond, matches("^diff_209[0-9]$")) %>%
  pivot_longer(cols = -Pond, names_to = "Year", values_to = "Difference")

boxplot(data_long$Difference ~ data_long$Pond)


# Step 2: Conduct ANOVA by grouping by Pond
res_YF45 <- aov(Difference ~ Pond, data = data_long)
summary(res_YF45)
            Df Sum Sq Mean Sq F value Pr(>F)
Pond        10   0.01  0.0006   0.001      1
Residuals   99  42.95  0.4338               
# Step 3: Tukey HSD
post_test_YF45 <- TukeyHSD(res_YF45)
post_test_YF45
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = Difference ~ Pond, data = data_long)

$Pond
                   diff        lwr       upr p adj
MP3-MP1   -2.912198e-02 -0.9997697 0.9415257     1
MP5-MP1   -1.092652e-02 -0.9815742 0.9597212     1
MP8-MP1   -9.914770e-03 -0.9805625 0.9607329     1
PL1-MP1   -1.407811e-02 -0.9847258 0.9565696     1
PL2-MP1   -1.383089e-02 -0.9844786 0.9568168     1
PL3-MP1   -9.249112e-03 -0.9798968 0.9613986     1
UBP1-MP1  -1.026779e-02 -0.9809155 0.9603799     1
UBP2-MP1  -1.021070e-02 -0.9808584 0.9604370     1
UBP3-MP1  -3.255073e-03 -0.9739028 0.9673926     1
UBP4-MP1  -6.333339e-03 -0.9769810 0.9643144     1
MP5-MP3    1.819546e-02 -0.9524522 0.9888432     1
MP8-MP3    1.920721e-02 -0.9514405 0.9898549     1
PL1-MP3    1.504387e-02 -0.9556038 0.9856916     1
PL2-MP3    1.529109e-02 -0.9553566 0.9859388     1
PL3-MP3    1.987287e-02 -0.9507748 0.9905206     1
UBP1-MP3   1.885419e-02 -0.9517935 0.9895019     1
UBP2-MP3   1.891129e-02 -0.9517364 0.9895590     1
UBP3-MP3   2.586691e-02 -0.9447808 0.9965146     1
UBP4-MP3   2.278864e-02 -0.9478591 0.9934363     1
MP8-MP5    1.011748e-03 -0.9696359 0.9716594     1
PL1-MP5   -3.151591e-03 -0.9737993 0.9674961     1
PL2-MP5   -2.904371e-03 -0.9735521 0.9677433     1
PL3-MP5    1.677406e-03 -0.9689703 0.9723251     1
UBP1-MP5   6.587301e-04 -0.9699890 0.9713064     1
UBP2-MP5   7.158229e-04 -0.9699319 0.9713635     1
UBP3-MP5   7.671445e-03 -0.9629763 0.9783191     1
UBP4-MP5   4.593179e-03 -0.9660545 0.9752409     1
PL1-MP8   -4.163339e-03 -0.9748110 0.9664844     1
PL2-MP8   -3.916119e-03 -0.9745638 0.9667316     1
PL3-MP8    6.656579e-04 -0.9699820 0.9713134     1
UBP1-MP8  -3.530180e-04 -0.9710007 0.9702947     1
UBP2-MP8  -2.959252e-04 -0.9709436 0.9703518     1
UBP3-MP8   6.659697e-03 -0.9639880 0.9773074     1
UBP4-MP8   3.581431e-03 -0.9670663 0.9742291     1
PL2-PL1    2.472194e-04 -0.9704005 0.9708949     1
PL3-PL1    4.828997e-03 -0.9658187 0.9754767     1
UBP1-PL1   3.810321e-03 -0.9668374 0.9744580     1
UBP2-PL1   3.867414e-03 -0.9667803 0.9745151     1
UBP3-PL1   1.082304e-02 -0.9598247 0.9814707     1
UBP4-PL1   7.744770e-03 -0.9629029 0.9783925     1
PL3-PL2    4.581777e-03 -0.9660659 0.9752295     1
UBP1-PL2   3.563101e-03 -0.9670846 0.9742108     1
UBP2-PL2   3.620194e-03 -0.9670275 0.9742679     1
UBP3-PL2   1.057582e-02 -0.9600719 0.9812235     1
UBP4-PL2   7.497550e-03 -0.9631501 0.9781452     1
UBP1-PL3  -1.018676e-03 -0.9716664 0.9696290     1
UBP2-PL3  -9.615831e-04 -0.9716093 0.9696861     1
UBP3-PL3   5.994039e-03 -0.9646537 0.9766417     1
UBP4-PL3   2.915773e-03 -0.9677319 0.9735635     1
UBP2-UBP1  5.709279e-05 -0.9705906 0.9707048     1
UBP3-UBP1  7.012715e-03 -0.9636350 0.9776604     1
UBP4-UBP1  3.934449e-03 -0.9667132 0.9745821     1
UBP3-UBP2  6.955622e-03 -0.9636921 0.9776033     1
UBP4-UBP2  3.877356e-03 -0.9667703 0.9745251     1
UBP4-UBP3 -3.078266e-03 -0.9737260 0.9675694     1

Making plots of error by season

2012-2020

# Extract unique pond names from the dataframe
short_names <- unique(Mod_YF45$pond_name)

# Initialize an empty dataframe to store monthly mean results
monthly_means <- data.frame(Pond = character(), Month = character(), AvgTemp = numeric(), Year = numeric(), stringsAsFactors = FALSE)

# Convert 'time' column to Date class
Mod_YF45$time <- as.Date(Mod_YF45$time, format="%Y-%m-%d")

# Extract year and month from 'time' column
Mod_YF45$Year <- format(Mod_YF45$time, "%Y")
Mod_YF45$Month <- format(Mod_YF45$time, "%B")

# Loop through each unique pond name
for (short_name in short_names) {
  # Filter data for the current pond
  pond_data <- subset(Mod_YF45, pond_name == short_name)
  
  # Loop through each month
  for (month in month.name) {
    # Filter data for the current month
    filtered_data <- subset(pond_data, Month == month)
    
    # Calculate the mean of 'med' for the current month
    avg_med <- mean(filtered_data$med, na.rm = TRUE)
    
    # Append results to monthly_means dataframe
    monthly_means <- rbind(monthly_means, data.frame(Pond = short_name, Month = month, AvgTemp = avg_med, Year = 2020))
  }
}

# Print the monthly means dataframe
print(monthly_means)

# Plotting the data
ggplot(monthly_means, aes(x = Month, y = AvgTemp, color = Pond, group = Pond)) +
  geom_line() +
  geom_point() +
  scale_x_discrete(limits = month.name) +
  labs(title = "Monthly Average Temperatures for Each Pond",
       x = "Month",
       y = "Average Temperature",
       color = "Pond") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

2030, 2060, and 2090

# Define the correct order for months
month_order <- c("January", "February", "March", "April", "May", "June", 
                  "July", "August", "September", "October", "November", "December")

# Recalculate monthly averages with correct month ordering
calculate_monthly_averages <- function(data, decade_start, decade_end) {
  # Initialize empty dataframe to store monthly averages
  monthly_avg_table <- data.frame(Pond = character(), Month = factor(), AvgTemp = numeric(), Year = integer(), stringsAsFactors = FALSE)
  
  # Loop through each year in the decade
  for (yr in decade_start:decade_end) {
    # Filter data for the current year
    yearly_data <- data %>%
      filter(year(time) == yr)
    
    # Loop through each pond
    for (pond_name in unique(data$pond_name)) {
      pond_data <- yearly_data %>%
        filter(pond_name == pond_name)
      
      # Loop through each month
      for (month in month_order) {
        # Filter data for the current month
        monthly_data <- pond_data %>%
          filter(format(time, "%B") == month)
        
        # Calculate the mean of 'med' for the current month
        avg_temp <- mean(monthly_data$med, na.rm = TRUE)
        
        # Append results to monthly_avg_table dataframe
        monthly_avg_table <- rbind(monthly_avg_table, data.frame(Pond = pond_name, Month = factor(month, levels = month_order), AvgTemp = avg_temp, Year = yr))
      }
    }
  }
  
  return(monthly_avg_table)
}

# Calculate monthly averages for each decade
monthly_avgX50_table_2030s <- calculate_monthly_averages(Mod_YF45, 2030, 2039)
monthly_avgX50_table_2060s <- calculate_monthly_averages(Mod_YF45, 2060, 2069)
monthly_avgX50_table_2090s <- calculate_monthly_averages(Mod_YF45, 2090, 2099)

Combine all the monthly average tables into one dataframe

# Add a Decade column to each dataframe
monthly_means <- monthly_means %>%
  mutate(Decade = "2020s")

monthly_avgX50_table_2030s <- monthly_avgX50_table_2030s %>%
  mutate(Decade = "2030s")

monthly_avgX50_table_2060s <- monthly_avgX50_table_2060s %>%
  mutate(Decade = "2060s")

monthly_avgX50_table_2090s <- monthly_avgX50_table_2090s %>%
  mutate(Decade = "2090s")

# Combine all monthly average tables into one dataframe
combined_monthly_avg <- bind_rows(
  monthly_means,
  monthly_avgX50_table_2030s,
  monthly_avgX50_table_2060s,
  monthly_avgX50_table_2090s
)

# Print the combined dataframe
print(combined_monthly_avg)

Calculate the differences here as compared to 2020

# Define the reference year
reference_year <- 2020

# Check if the column exists and is correctly populated
summary(combined_monthly_avg)
     Pond              Month              AvgTemp            Year         Decade         
 Length:4092        Length:4092        Min.   :-2.253   Min.   :2020   Length:4092       
 Class :character   Class :character   1st Qu.: 6.198   1st Qu.:2036   Class :character  
 Mode  :character   Mode  :character   Median : 9.924   Median :2064   Mode  :character  
                                       Mean   : 9.948   Mean   :2063                     
                                       3rd Qu.:13.743   3rd Qu.:2092                     
                                       Max.   :17.834   Max.   :2099                     
# Calculate average temperature for each month in the reference year
ref_year_avg <- combined_monthly_avg %>%
  filter(Year == reference_year) %>%
  group_by(Month) %>%
  summarise(avg_temp_ref_year = mean(AvgTemp, na.rm = TRUE))

# Join reference year averages with the main dataset
combined_monthly_avg_with_diff <- combined_monthly_avg %>%
  left_join(ref_year_avg, by = "Month") %>%
  mutate(diff_AvgTemp = AvgTemp - avg_temp_ref_year) %>%
  select(-avg_temp_ref_year)  # Remove the reference year average column

# Display the structure to verify
str(combined_monthly_avg_with_diff)
'data.frame':   4092 obs. of  6 variables:
 $ Pond        : chr  "MP1" "MP1" "MP1" "MP1" ...
 $ Month       : chr  "January" "February" "March" "April" ...
 $ AvgTemp     : num  5.36 4.78 4.22 6.15 9.3 ...
 $ Year        : num  2020 2020 2020 2020 2020 2020 2020 2020 2020 2020 ...
 $ Decade      : chr  "2020s" "2020s" "2020s" "2020s" ...
 $ diff_AvgTemp: num  0.49 0.489 0.483 0.489 0.505 ...
# Filter out data for the reference year
DeltaMonthly_YF45 <- combined_monthly_avg_with_diff %>%
  filter(Year != reference_year)

# Display the filtered data
print(DeltaMonthly_YF45)
NA

Calculate mean differences

library(dplyr)

DeltaMonthly_YF45

DiffMonthly_YF45 <- DeltaMonthly_YF45 %>%
  select(Pond, Month, Year, diff_AvgTemp)

# Create a new column based on year ranges
DiffMonthly_YF45$Decade <- ifelse(DiffMonthly_YF45$Year >= 2030 & DiffMonthly_YF45$Year < 2040, "2030s",
                          ifelse(DiffMonthly_YF45$Year >= 2060 & DiffMonthly_YF45$Year < 2070, "2060s",
                          ifelse(DiffMonthly_YF45$Year >= 2090 & DiffMonthly_YF45$Year < 2100, "2090s",
                          "Other")))

# Print the updated data frame
print(DiffMonthly_YF45)
  
# Convert Month to Date type
DiffMonthly_YF45 <- DiffMonthly_YF45 %>%
  mutate(Month = as.Date(paste0(Month, " 1 ", Year), format = "%B %d %Y"))

print(DiffMonthly_YF45)

# Group by Pond and Month, then calculate mean and standard deviation of diff_AvgTemp
summary_stats <- DiffMonthly_YF45 %>%
  dplyr::mutate(Month = format(Month, "%m")) %>%  # Extracts YYYY-MM format
  dplyr::group_by(Pond, Month, Decade) %>%
  dplyr::summarise(
    mean_diff_AvgTemp = mean(diff_AvgTemp, na.rm = TRUE),
    sd_diff_AvgTemp = sd(diff_AvgTemp, na.rm = TRUE)
  )
`summarise()` has grouped output by 'Pond', 'Month'. You can override using the `.groups` argument.
# View the summary statistics
print(summary_stats)

# Group by just Month, then calculate mean and standard deviation of diff_AvgTemp
summary_stats2 <- DiffMonthly_YF45 %>%
  dplyr::mutate(Month = format(Month, "%m")) %>%  # Extracts YYYY-MM format
  dplyr::group_by(Month, Decade) %>%
  dplyr::summarise(
    mean_diff_AvgTemp = mean(diff_AvgTemp, na.rm = TRUE),
    sd_diff_AvgTemp = sd(diff_AvgTemp, na.rm = TRUE)
  )
`summarise()` has grouped output by 'Month'. You can override using the `.groups` argument.
# View the summary statistics
print(summary_stats2)

Plotting the monthly temperature change graphs

2030s

summary_stats # grouped by month and pond
summary_stats2 # grouped by just month

# 2. Monthly averages across ponds
MonthlyStats_2030 <- summary_stats2 %>%
  filter(Decade == "2030s") 

ggplot(data = MonthlyStats_2030, aes(x = Month)) +
  geom_point(aes(y = mean_diff_AvgTemp)) +
  theme_classic()


# Convert Month from character to numeric to ensure proper ordering in ggplot
MonthlyStats_2030$Month <- as.numeric(MonthlyStats_2030$Month)

# Plot using ggplot
MonthlyStats_2030Plot <- ggplot(data = MonthlyStats_2030, aes(x = Month)) +
  geom_line(aes(y = mean_diff_AvgTemp)) +  # Point plot with mean values
  geom_hline(yintercept = 0, linetype = "dashed", color = "black") +  # Horizontal dashed line at y = 0
  geom_ribbon(aes(ymin = mean_diff_AvgTemp - sd_diff_AvgTemp, ymax = mean_diff_AvgTemp + sd_diff_AvgTemp), fill = "blue", alpha = 0.3) +  # Ribbon for positive and negative error based on sd values
  scale_x_continuous(breaks = 1:12, labels = month.abb) +  # Adjust x-axis labels to show month abbreviations
  ylim(-4,6)+
  theme_classic() +
  labs(x = "", y = "Delta Temp (C)") +
  theme(axis.text.x = element_text(angle = 65, hjust = 1)) +
  theme(axis.title = element_text(size = 16),
        axis.text = element_text(size = 14))
MonthlyStats_2030Plot

2060s

# 2. Monthly averages across ponds
MonthlyStats_2060 <- summary_stats2 %>%
  filter(Decade == "2060s") 

ggplot(data = MonthlyStats_2060, aes(x = Month)) +
  geom_point(aes(y = mean_diff_AvgTemp)) +
  theme_classic()

# Convert Month from character to numeric to ensure proper ordering in ggplot

MonthlyStats_2060$Month <- as.numeric(MonthlyStats_2060$Month)

# Plot using ggplot
MonthlyStats_2060Plot <- ggplot(data = MonthlyStats_2060, aes(x = Month)) +
  geom_line(aes(y = mean_diff_AvgTemp)) +  # Point plot with mean values
  geom_hline(yintercept = 0, linetype = "dashed", color = "black") +  # Horizontal dashed line at y = 0
  geom_ribbon(aes(ymin = mean_diff_AvgTemp - sd_diff_AvgTemp, ymax = mean_diff_AvgTemp + sd_diff_AvgTemp), fill = "blue", alpha = 0.3) +  # Ribbon for positive and negative error based on sd values
  scale_x_continuous(breaks = 1:12, labels = month.abb) +  # Adjust x-axis labels to show month abbreviations
  ylim(-4,6)+
  theme_classic() +
  labs(x = "", y = "") +
  theme(axis.text.x = element_text(angle = 65, hjust = 1)) +
  theme(axis.title = element_text(size = 16),
        axis.text = element_text(size = 14))+
  theme(axis.text.y = element_blank(),  # Remove Y-axis tick mark labels
        axis.ticks.y = element_blank())
MonthlyStats_2060Plot

2090s

# 2. Monthly averages across ponds
MonthlyStats_2090 <- summary_stats2 %>%
  filter(Decade == "2090s") 

ggplot(data = MonthlyStats_2090, aes(x = Month)) +
  geom_point(aes(y = mean_diff_AvgTemp)) +
  theme_classic()


# Convert Month from character to numeric to ensure proper ordering in ggplot
MonthlyStats_2090$Month <- as.numeric(MonthlyStats_2090$Month)

# Plot using ggplot
MonthlyStats_2090Plot <- ggplot(data = MonthlyStats_2090, aes(x = Month)) +
  geom_line(aes(y = mean_diff_AvgTemp)) +  # Point plot with mean values
  geom_hline(yintercept = 0, linetype = "dashed", color = "black") +  # Horizontal dashed line at y = 0
  geom_ribbon(aes(ymin = mean_diff_AvgTemp - sd_diff_AvgTemp, ymax = mean_diff_AvgTemp + sd_diff_AvgTemp), fill = "blue", alpha = 0.3) +  # Ribbon for positive and negative error based on sd values
  scale_x_continuous(breaks = 1:12, labels = month.abb) +  # Adjust x-axis labels to show month abbreviations
  ylim(-4,6)+
  theme_classic() +
  theme(axis.text.x = element_text(angle = 65, hjust = 1)) +
  labs(x = "", y = "") +
  theme(axis.title = element_text(size = 16),
        axis.text = element_text(size = 14))+
  theme(axis.text.y = element_blank(),  # Remove Y-axis tick mark labels
        axis.ticks.y = element_blank())
MonthlyStats_2090Plot

Combine the plots together here for now

# Combine plots into a panel plot
DeltaMonth_YF45_plot <- ggarrange(MonthlyStats_2030Plot, MonthlyStats_2060Plot, MonthlyStats_2090Plot, ncol = 3)

# Save the combined plot
ggsave("Corr_DeltaMonthYF45.png", plot = DeltaMonth_YF45_plot, width = 12, height = 3)

Create .csv files of the data for these graphs

write.csv(MonthlyStats_2030, file = "Corr_MonthlyStatsYF45_2030.csv")
write.csv(MonthlyStats_2060, file = "Corr_MonthlyStatsYF45_2060.csv")
write.csv(MonthlyStats_2090, file = "Corr_MonthlyStatsYF45_2090.csv")
LS0tCnRpdGxlOiAiUG9uZCBUZW1wcyAtIERlbHRhIEdyYXBocyBhbmQgU2Vhc29uYWwgVHJlbmRzIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tClRoaXMgaXMgY29kZSB1c2VkIHRvIG1ha2UgcGxvdHMgYmFzZWQgb24gb3V0cHV0IGZyb20gdGhlICJJbmRpdmlkdWFsUG9uZE1vZGVsc19Gb3JlY2FzdHM4NSIgZm9yIGJvdGh0aGUgQ1IgYW5kIFlGClJlYWQgaW4gdGhlIG91dHB1dCBmaWxlcyBmb3IgZWFjaCBwb25kL1JDUCBjb21iaW5hdGlvbiB0aGVuIHdvcmsgb24gZGVsdGEgZmlndXJlcyBhbmQgZmlndXJlcyBsaWtlIEhhbWxldCBldCBhbC4gMjAyMAoKYGBge3J9CnJtKGxpc3QgPSBscygpKQoKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkocmphZ3MpCmxpYnJhcnkoZ2dwbG90MikKCnNldC5zZWVkKDEpCmBgYAoKU3RhcnRpbmcgd2l0aCB0aGUgWWFrdXRhdCBGb3JlbGFuZHMKClJDUCA0NQoKIyBSZWFkaW5nIGluIHRoZSBkYXRhCmBgYHtyfQpNb2RfWUY0NSA8LSByZWFkLmNzdigiQ29ycl9Nb2RfWUY0NS5jc3YiLCBoZWFkZXIgPSBUKQpgYGAKCiAKIyMjIDIwMTItMjAyMApgYGB7cn0KIyBMaXN0IG9mIHVuaXF1ZSBwb25kIG5hbWVzIGZyb20gdGhlIGRhdGFmcmFtZQpwb25kX25hbWVzIDwtIHVuaXF1ZShNb2RfWUY0NSRwb25kX25hbWUpCgojIEluaXRpYWxpemUgYW4gZW1wdHkgZGF0YWZyYW1lIHRvIHN0b3JlIHJlc3VsdHMKYXZnTWVkXzIwMjAgPC0gZGF0YS5mcmFtZShQb25kID0gcG9uZF9uYW1lcywgQXZnTWVkXzIwMjAgPSBudW1lcmljKGxlbmd0aChwb25kX25hbWVzKSkpCgojIExvb3AgdGhyb3VnaCBlYWNoIHBvbmQgbmFtZQpmb3IgKGkgaW4gc2VxX2Fsb25nKHBvbmRfbmFtZXMpKSB7CiAgcG9uZF9uYW1lIDwtIHBvbmRfbmFtZXNbaV0KICAKICAjIEZpbHRlciBkYXRhIGZvciB0aGUgY3VycmVudCBwb25kIGFuZCBmb3IgZGF0ZXMgYmVmb3JlIEphbnVhcnkgMSwgMjAyMQogIGZpbHRlcmVkX2RhdGEgPC0gTW9kX1lGNDUgJT4lCiAgICBmaWx0ZXIocG9uZF9uYW1lID09ICEhcG9uZF9uYW1lLCBhcy5EYXRlKHRpbWUpIDwgYXMuRGF0ZSgiMjAyMS0wMS0wMSIpKQogIAogICMgQ2FsY3VsYXRlIHRoZSBtZWFuIG9mICdtZWQnICh3aGljaCBjb3JyZXNwb25kcyB0byBYNTAlKQogIGF2Z19tZWQgPC0gbWVhbihmaWx0ZXJlZF9kYXRhJG1lZCwgbmEucm0gPSBUUlVFKQogIAogICMgU3RvcmUgdGhlIHJlc3VsdCBpbiB0aGUgZGF0YWZyYW1lCiAgYXZnTWVkXzIwMjBbaSwgIkF2Z01lZF8yMDIwIl0gPC0gYXZnX21lZAp9CgojIFByaW50IHRoZSBkYXRhZnJhbWUKcHJpbnQoYXZnTWVkXzIwMjApCmBgYAoKIyMjIDIwMzAtMjAzOQpgYGB7cn0KbGlicmFyeShsdWJyaWRhdGUpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkodGlkeXIpCmxpYnJhcnkoZ2dwbG90MikKCiMgTGlzdCBvZiB1bmlxdWUgcG9uZCBuYW1lcyBmcm9tIHRoZSBkYXRhZnJhbWUKcG9uZF9uYW1lcyA8LSB1bmlxdWUoTW9kX1lGNDUkcG9uZF9uYW1lKQoKIyBJbml0aWFsaXplIGEgZGF0YWZyYW1lIHRvIHN0b3JlIHJlc3VsdHMgd2l0aCB5ZWFycyBhcyBjb2x1bW5zCmF2Z01lZF8yMDMwIDwtIGRhdGEuZnJhbWUoUG9uZCA9IHBvbmRfbmFtZXMpCgojIExvb3AgdGhyb3VnaCBlYWNoIHllYXIgZnJvbSAyMDMwIHRvIDIwMzkKZm9yICh5ciBpbiAyMDMwOjIwMzkpIHsKICAjIENhbGN1bGF0ZSBhdmVyYWdlIG1lZGlhbnMgZm9yIGVhY2ggeWVhciBhbmQgc3RvcmUgYXMgYSBuZXcgY29sdW1uCiAgYXZnTWVkX2NvbCA8LSBzYXBwbHkocG9uZF9uYW1lcywgZnVuY3Rpb24ocG9uZF9uYW1lKSB7CiAgICB5ZWFybHlfZGF0YSA8LSBNb2RfWUY0NSAlPiUKICAgICAgZmlsdGVyKHBvbmRfbmFtZSA9PSAhIXBvbmRfbmFtZSwgeWVhcihhcy5EYXRlKHRpbWUpKSA9PSB5cikKICAgIAogICAgYXZnX21lZCA8LSBtZWFuKHllYXJseV9kYXRhJG1lZCwgbmEucm0gPSBUUlVFKQogICAgcmV0dXJuKGF2Z19tZWQpCiAgfSkKICAKICAjIEFkZCB0aGUgcmVzdWx0cyBhcyBhIG5ldyBjb2x1bW4gdG8gdGhlIGRhdGFmcmFtZQogIGF2Z01lZF8yMDMwW1thcy5jaGFyYWN0ZXIoeXIpXV0gPC0gYXZnTWVkX2NvbAp9CgojIFByaW50IHRoZSBmaW5hbCBkYXRhZnJhbWUKcHJpbnQoYXZnTWVkXzIwMzApCgojIENvbnZlcnQgdG8gbG9uZyBmb3JtYXQgZm9yIGdncGxvdDIKYXZnTWVkXzIwMzBfbG9uZyA8LSBhdmdNZWRfMjAzMCAlPiUKICBwaXZvdF9sb25nZXIoY29scyA9IC1Qb25kLCBuYW1lc190byA9ICJZZWFyIiwgdmFsdWVzX3RvID0gIkF2Z01lZCIpCgojIFBsb3QgdGhlIGRhdGEKZ2dwbG90KGF2Z01lZF8yMDMwX2xvbmcsIGFlcyh4ID0gWWVhciwgeSA9IEF2Z01lZCwgY29sb3IgPSBQb25kLCBncm91cCA9IFBvbmQpKSArCiAgZ2VvbV9saW5lKCkgKwogIGdlb21fcG9pbnQoKSArCiAgbGFicyh0aXRsZSA9ICJBdmVyYWdlIE1lZGlhbiBwZXIgUG9uZCBmcm9tIDIwMzAgdG8gMjAzOSIsCiAgICAgICB4ID0gIlllYXIiLAogICAgICAgeSA9ICJBdmVyYWdlIE1lZGlhbiIpICsKICB0aGVtZV9taW5pbWFsKCkKYGBgCgojIyMgMjA2MC0yMDY5CmBgYHtyfQpsaWJyYXJ5KGx1YnJpZGF0ZSkKbGlicmFyeShkcGx5cikKbGlicmFyeSh0aWR5cikKbGlicmFyeShnZ3Bsb3QyKQoKIyBMaXN0IG9mIHVuaXF1ZSBwb25kIG5hbWVzIGZyb20gdGhlIGRhdGFmcmFtZQpwb25kX25hbWVzIDwtIHVuaXF1ZShNb2RfWUY0NSRwb25kX25hbWUpCgojIEluaXRpYWxpemUgYSBkYXRhZnJhbWUgdG8gc3RvcmUgcmVzdWx0cyB3aXRoIHllYXJzIGFzIGNvbHVtbnMKYXZnTWVkXzIwNjAgPC0gZGF0YS5mcmFtZShQb25kID0gcG9uZF9uYW1lcykKCiMgTG9vcCB0aHJvdWdoIGVhY2ggeWVhciBmcm9tIDIwNjAgdG8gMjA2OQpmb3IgKHlyIGluIDIwNjA6MjA2OSkgewogICMgQ2FsY3VsYXRlIGF2ZXJhZ2UgbWVkaWFucyBmb3IgZWFjaCB5ZWFyIGFuZCBzdG9yZSBhcyBhIG5ldyBjb2x1bW4KICBhdmdNZWRfY29sIDwtIHNhcHBseShwb25kX25hbWVzLCBmdW5jdGlvbihwb25kX25hbWUpIHsKICAgIHllYXJseV9kYXRhIDwtIE1vZF9ZRjQ1ICU+JQogICAgICBmaWx0ZXIocG9uZF9uYW1lID09ICEhcG9uZF9uYW1lLCB5ZWFyKGFzLkRhdGUodGltZSkpID09IHlyKQogICAgCiAgICBhdmdfbWVkIDwtIG1lYW4oeWVhcmx5X2RhdGEkbWVkLCBuYS5ybSA9IFRSVUUpCiAgICByZXR1cm4oYXZnX21lZCkKICB9KQogIAogICMgQWRkIHRoZSByZXN1bHRzIGFzIGEgbmV3IGNvbHVtbiB0byB0aGUgZGF0YWZyYW1lCiAgYXZnTWVkXzIwNjBbW2FzLmNoYXJhY3Rlcih5cildXSA8LSBhdmdNZWRfY29sCn0KCiMgUHJpbnQgdGhlIGZpbmFsIGRhdGFmcmFtZQpwcmludChhdmdNZWRfMjA2MCkKCiMgQ29udmVydCB0byBsb25nIGZvcm1hdCBmb3IgZ2dwbG90MgphdmdNZWRfMjA2MF9sb25nIDwtIGF2Z01lZF8yMDYwICU+JQogIHBpdm90X2xvbmdlcihjb2xzID0gLVBvbmQsIG5hbWVzX3RvID0gIlllYXIiLCB2YWx1ZXNfdG8gPSAiQXZnTWVkIikKCiMgUGxvdCB0aGUgZGF0YQpnZ3Bsb3QoYXZnTWVkXzIwNjBfbG9uZywgYWVzKHggPSBZZWFyLCB5ID0gQXZnTWVkLCBjb2xvciA9IFBvbmQsIGdyb3VwID0gUG9uZCkpICsKICBnZW9tX2xpbmUoKSArCiAgZ2VvbV9wb2ludCgpICsKICBsYWJzKHRpdGxlID0gIkF2ZXJhZ2UgTWVkaWFuIHBlciBQb25kIGZyb20gMjA2MCB0byAyMDY5IiwKICAgICAgIHggPSAiWWVhciIsCiAgICAgICB5ID0gIkF2ZXJhZ2UgTWVkaWFuIikgKwogIHRoZW1lX21pbmltYWwoKQpgYGAKCiMjIyAyMDkwLTIwOTkKYGBge3J9CmxpYnJhcnkobHVicmlkYXRlKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KHRpZHlyKQpsaWJyYXJ5KGdncGxvdDIpCgojIExpc3Qgb2YgdW5pcXVlIHBvbmQgbmFtZXMgZnJvbSB0aGUgZGF0YWZyYW1lCnBvbmRfbmFtZXMgPC0gdW5pcXVlKE1vZF9ZRjQ1JHBvbmRfbmFtZSkKCiMgSW5pdGlhbGl6ZSBhIGRhdGFmcmFtZSB0byBzdG9yZSByZXN1bHRzIHdpdGggeWVhcnMgYXMgY29sdW1ucwphdmdNZWRfMjA5MCA8LSBkYXRhLmZyYW1lKFBvbmQgPSBwb25kX25hbWVzKQoKIyBMb29wIHRocm91Z2ggZWFjaCB5ZWFyIGZyb20gMjA5MCB0byAyMDk5CmZvciAoeXIgaW4gMjA5MDoyMDk5KSB7CiAgIyBDYWxjdWxhdGUgYXZlcmFnZSBtZWRpYW5zIGZvciBlYWNoIHllYXIgYW5kIHN0b3JlIGFzIGEgbmV3IGNvbHVtbgogIGF2Z01lZF9jb2wgPC0gc2FwcGx5KHBvbmRfbmFtZXMsIGZ1bmN0aW9uKHBvbmRfbmFtZSkgewogICAgeWVhcmx5X2RhdGEgPC0gTW9kX1lGNDUgJT4lCiAgICAgIGZpbHRlcihwb25kX25hbWUgPT0gISFwb25kX25hbWUsIHllYXIoYXMuRGF0ZSh0aW1lKSkgPT0geXIpCiAgICAKICAgIGF2Z19tZWQgPC0gbWVhbih5ZWFybHlfZGF0YSRtZWQsIG5hLnJtID0gVFJVRSkKICAgIHJldHVybihhdmdfbWVkKQogIH0pCiAgCiAgIyBBZGQgdGhlIHJlc3VsdHMgYXMgYSBuZXcgY29sdW1uIHRvIHRoZSBkYXRhZnJhbWUKICBhdmdNZWRfMjA5MFtbYXMuY2hhcmFjdGVyKHlyKV1dIDwtIGF2Z01lZF9jb2wKfQoKIyBQcmludCB0aGUgZmluYWwgZGF0YWZyYW1lCnByaW50KGF2Z01lZF8yMDkwKQoKIyBDb252ZXJ0IHRvIGxvbmcgZm9ybWF0IGZvciBnZ3Bsb3QyCmF2Z01lZF8yMDkwX2xvbmcgPC0gYXZnTWVkXzIwOTAgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAtUG9uZCwgbmFtZXNfdG8gPSAiWWVhciIsIHZhbHVlc190byA9ICJBdmdNZWQiKQoKIyBQbG90IHRoZSBkYXRhCmdncGxvdChhdmdNZWRfMjA5MF9sb25nLCBhZXMoeCA9IFllYXIsIHkgPSBBdmdNZWQsIGNvbG9yID0gUG9uZCwgZ3JvdXAgPSBQb25kKSkgKwogIGdlb21fbGluZSgpICsKICBnZW9tX3BvaW50KCkgKwogIGxhYnModGl0bGUgPSAiQXZlcmFnZSBNZWRpYW4gcGVyIFBvbmQgZnJvbSAyMDkwIHRvIDIwOTkiLAogICAgICAgeCA9ICJZZWFyIiwKICAgICAgIHkgPSAiQXZlcmFnZSBNZWRpYW4iKSArCiAgdGhlbWVfbWluaW1hbCgpCmBgYApgYGB7cn0KIyBSZW5hbWUgY29sdW1ucyB0byByZWZsZWN0IG9ubHkgdGhlIHllYXJzCmF2Z01lZF8yMDIwIDwtIGF2Z01lZF8yMDIwICU+JQogIHJlbmFtZShBdmdNZWRfMjAyMCA9IEF2Z01lZF8yMDIwKQoKYXZnTWVkXzIwMzAgPC0gYXZnTWVkXzIwMzAgJT4lCiAgcmVuYW1lKGAyMDMwYCA9IGAyMDMwYCkKCmF2Z01lZF8yMDYwIDwtIGF2Z01lZF8yMDYwICU+JQogIHJlbmFtZShgMjA2MGAgPSBgMjA2MGApCgphdmdNZWRfMjA5MCA8LSBhdmdNZWRfMjA5MCAlPiUKICByZW5hbWUoYDIwOTBgID0gYDIwOTBgKQoKIyBDb21iaW5lIHRoZSBkYXRhIGZyYW1lcwpjb21iaW5lZF9hdmdNZWQgPC0gYXZnTWVkXzIwMjAgJT4lCiAgbGVmdF9qb2luKGF2Z01lZF8yMDMwLCBieSA9ICJQb25kIikgJT4lCiAgbGVmdF9qb2luKGF2Z01lZF8yMDYwLCBieSA9ICJQb25kIikgJT4lCiAgbGVmdF9qb2luKGF2Z01lZF8yMDkwLCBieSA9ICJQb25kIikKCiMgUHJpbnQgdGhlIGZpbmFsIGRhdGFmcmFtZQpwcmludChjb21iaW5lZF9hdmdNZWQpCgojIENvbnZlcnQgdG8gbG9uZyBmb3JtYXQgZm9yIGdncGxvdDIsIGV4Y2x1ZGluZyBBdmdNZWRfMjAyMAphdmdNZWRfbG9uZyA8LSBjb21iaW5lZF9hdmdNZWQgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAtUG9uZCwgbmFtZXNfdG8gPSAiWWVhciIsIHZhbHVlc190byA9ICJBdmdNZWQiKSAlPiUKICBmaWx0ZXIoWWVhciAlaW4lIGFzLmNoYXJhY3RlcigyMDIxOjIxOTkpKQoKIyBQbG90IHRoZSBkYXRhCmdncGxvdChhdmdNZWRfbG9uZywgYWVzKHggPSBZZWFyLCB5ID0gQXZnTWVkLCBjb2xvciA9IFBvbmQsIGdyb3VwID0gUG9uZCkpICsKICBnZW9tX2xpbmUoKSArCiAgZ2VvbV9wb2ludCgpICsKICBsYWJzKHRpdGxlID0gIkF2ZXJhZ2UgTWVkaWFuIHBlciBQb25kIGluIHRoZSBZRiAtIFJDUCA0LjUiLAogICAgICAgeCA9ICJZZWFyIiwKICAgICAgIHkgPSAiQXZlcmFnZSBNZWRpYW4iKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpLCMgUm90YXRlIHgtYXhpcyBsYWJlbHMgYnkgNDUgZGVncmVlcwogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKSAgCmBgYAoKCiMgQ2FsY3VhdGUgdGhlIGRpZmZlcmVuY2VzIGhlcmUgYXMgbmV3IGNvbHVtbnMgaW4gdGhlIGRhdGFmcmFtZQoKYGBge3J9CmxpYnJhcnkoZHBseXIpCgojIEFzc3VtaW5nIGNvbWJpbmVkX2F2Z01lZCBpcyBsb2FkZWQgYW5kIHN0cnVjdHVyZSB2ZXJpZmllZApEZWx0YV9jb21iaW5lZF9hdmdNZWQgPC0gY29tYmluZWRfYXZnTWVkICAjIFVzZSB5b3VyIGFjdHVhbCBkYXRhZnJhbWUKCiMgQ29sdW1ucyB0byBjYWxjdWxhdGUgZGlmZmVyZW5jZXMgZm9yCnllYXJzIDwtIGMoIjIwMzAiLCAiMjAzMSIsICIyMDMyIiwgIjIwMzMiLCAiMjAzNCIsIAogICAgICAgICAgICIyMDM1IiwgIjIwMzYiLCAiMjAzNyIsICIyMDM4IiwgIjIwMzkiLCAKICAgICAgICAgICAiMjA2MCIsICIyMDYxIiwgIjIwNjIiLCAiMjA2MyIsICIyMDY0IiwgCiAgICAgICAgICAgIjIwNjUiLCAiMjA2NiIsICIyMDY3IiwgIjIwNjgiLCAiMjA2OSIsIAogICAgICAgICAgICIyMDkwIiwgIjIwOTEiLCAiMjA5MiIsICIyMDkzIiwgIjIwOTQiLCAKICAgICAgICAgICAiMjA5NSIsICIyMDk2IiwgIjIwOTciLCAiMjA5OCIsICIyMDk5IikKCiMgTG9vcCB0aHJvdWdoIGVhY2ggeWVhciBhbmQgY2FsY3VsYXRlIHRoZSBkaWZmZXJlbmNlCmZvciAoeWVhciBpbiB5ZWFycykgewogICMgQ3JlYXRlIGEgbmV3IGNvbHVtbiBmb3IgdGhlIGRpZmZlcmVuY2UKICBkaWZmX2NvbF9uYW1lIDwtIHBhc3RlMCgiZGlmZl8iLCB5ZWFyKQogIERlbHRhX2NvbWJpbmVkX2F2Z01lZFtbZGlmZl9jb2xfbmFtZV1dIDwtIERlbHRhX2NvbWJpbmVkX2F2Z01lZFtbeWVhcl1dIC0gRGVsdGFfY29tYmluZWRfYXZnTWVkJGBBdmdNZWRfMjAyMGAKfQoKIyBEaXNwbGF5IHRoZSBzdHJ1Y3R1cmUgb2YgRGVsdGFfY29tYmluZWRfYXZnTWVkIHRvIHZlcmlmeQpzdHIoRGVsdGFfY29tYmluZWRfYXZnTWVkKQpgYGAKCmBgYHtyfQojIENyZWF0ZSBhIG5ldyBkYXRhZnJhbWUgd2l0aCB0aGUgY2FsY3VsYXRlZCBtZWFucyBhbmQgc3RhbmRhcmQgZGV2aWF0aW9ucwpEZWx0YV9ZRjQ1IDwtIERlbHRhX2NvbWJpbmVkX2F2Z01lZCAlPiUKICBtdXRhdGUoCiAgICBNZWFuXzIwMzBfMjAzOSA9IHJvd01lYW5zKHNlbGVjdCguLCBzdGFydHNfd2l0aCgiZGlmZl8yMDMiKSksIG5hLnJtID0gVFJVRSksICAjIENhbGN1bGF0ZSByb3ctd2lzZSBtZWFuIGZvciBjb2x1bW5zIHN0YXJ0aW5nIHdpdGggImRpZmZfMjAzIgogICAgU0RfMjAzMF8yMDM5ID0gcm93U2RzKGFzLm1hdHJpeChzZWxlY3QoLiwgc3RhcnRzX3dpdGgoImRpZmZfMjAzIikpKSwgbmEucm0gPSBUUlVFKSwgICMgQ2FsY3VsYXRlIHJvdy13aXNlIFNEIGZvciBjb2x1bW5zIHN0YXJ0aW5nIHdpdGggImRpZmZfMjAzIgogICAgTWVhbl8yMDYwXzIwNjkgPSByb3dNZWFucyhzZWxlY3QoLiwgc3RhcnRzX3dpdGgoImRpZmZfMjA2IikpLCBuYS5ybSA9IFRSVUUpLCAgIyBDYWxjdWxhdGUgcm93LXdpc2UgbWVhbiBmb3IgY29sdW1ucyBzdGFydGluZyB3aXRoICJkaWZmXzIwNiIKICAgIFNEXzIwNjBfMjA2OSA9IHJvd1Nkcyhhcy5tYXRyaXgoc2VsZWN0KC4sIHN0YXJ0c193aXRoKCJkaWZmXzIwNiIpKSksIG5hLnJtID0gVFJVRSksICAjIENhbGN1bGF0ZSByb3ctd2lzZSBTRCBmb3IgY29sdW1ucyBzdGFydGluZyB3aXRoICJkaWZmXzIwNiIKICAgIE1lYW5fMjA5MF8yMDk5ID0gcm93TWVhbnMoc2VsZWN0KC4sIHN0YXJ0c193aXRoKCJkaWZmXzIwOSIpKSwgbmEucm0gPSBUUlVFKSwgICMgQ2FsY3VsYXRlIHJvdy13aXNlIG1lYW4gZm9yIGNvbHVtbnMgc3RhcnRpbmcgd2l0aCAiZGlmZl8yMDkiCiAgICBTRF8yMDkwXzIwOTkgPSByb3dTZHMoYXMubWF0cml4KHNlbGVjdCguLCBzdGFydHNfd2l0aCgiZGlmZl8yMDkiKSkpLCBuYS5ybSA9IFRSVUUpICAjIENhbGN1bGF0ZSByb3ctd2lzZSBTRCBmb3IgY29sdW1ucyBzdGFydGluZyB3aXRoICJkaWZmXzIwOSIKICApCgojIFByaW50IHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIG5ldyBkYXRhZnJhbWUKc3RyKERlbHRhX1lGNDUpCgojIE9wdGlvbmFsbHksIHZpZXcgdGhlIGZpcnN0IGZldyByb3dzIHRvIGNoZWNrIHRoZSBuZXcgY29sdW1ucwpoZWFkKERlbHRhX1lGNDUpCmBgYAoKIyMgUHV0IHRoZXNlIGludG8gdG90YWwgbWVhbi9zdGFuZGFyZCBkZXZpYXRpb25zCgpgYGB7cn0KIyBMb2FkIG5lY2Vzc2FyeSBsaWJyYXJpZXMKbGlicmFyeShkcGx5cikKCiMgU2VsZWN0IGFuZCByZW5hbWUgY29sdW1ucyBmcm9tIERlbHRhX1lGNDUKWUY0NV9kZWNhZGFsIDwtIERlbHRhX1lGNDUgJT4lCiAgc2VsZWN0KFBvbmQsIHN0YXJ0c193aXRoKCJNZWFuXyIpLCBzdGFydHNfd2l0aCgiU0RfIikpCgojIFJlbmFtZSBjb2x1bW5zIHdpdGhvdXQgdGhlICdZJyBwcmVmaXggZm9yIG1lYW5zCm5hbWVzKFlGNDVfZGVjYWRhbCkgPC0gc3ViKCJeTWVhbl8iLCAiTWVhbl8iLCBuYW1lcyhZRjQ1X2RlY2FkYWwpKQoKIyBSZW5hbWUgY29sdW1ucyB3aXRob3V0IHRoZSAnWScgcHJlZml4IGZvciBzdGFuZGFyZCBkZXZpYXRpb25zCm5hbWVzKFlGNDVfZGVjYWRhbCkgPC0gc3ViKCJeU0RfIiwgIlNEXyIsIG5hbWVzKFlGNDVfZGVjYWRhbCkpCgojIFByaW50IHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIHVwZGF0ZWQgZGF0YWZyYW1lCnN0cihZRjQ1X2RlY2FkYWwpCgojIE9wdGlvbmFsbHksIHZpZXcgdGhlIGZpcnN0IGZldyByb3dzIHRvIGNoZWNrIHRoZSBuZXcgY29sdW1ucwpoZWFkKFlGNDVfZGVjYWRhbCkKYGBgCgojIE1ha2luZyB0aGUgcGxvdHMgb2YgdGhlc2UgZGVsdGFzCmBgYHtyfQojIExvYWQgcmVxdWlyZWQgcGFja2FnZXMKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGdyaWRFeHRyYSkKbGlicmFyeShnZ3B1YnIpCgojIENyZWF0ZSBhIGdyb3VwZWQgYmFyIHBsb3Qgd2l0aCBlcnJvciBiYXJzIGZvciBNZWFuIDIwMzAKcGxvdF8yMDMwIDwtIGdncGxvdChZRjQ1X2RlY2FkYWwsIGFlcyh4ID0gUG9uZCwgeSA9IE1lYW5fMjAzMF8yMDM5KSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gIiNGRkQ5MkYiLCBjb2xvciA9ICJibGFjayIpICsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gTWVhbl8yMDMwXzIwMzkgLSBTRF8yMDMwXzIwMzksIHltYXggPSBNZWFuXzIwMzBfMjAzOSArIFNEXzIwMzBfMjAzOSksCiAgICAgICAgICAgICAgICB3aWR0aCA9IDAuNCwgICMgQWRqdXN0IHRoZSB3aWR0aCBvZiBlcnJvciBiYXJzIGFzIG5lZWRlZAogICAgICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuOSkpICsKICBsYWJzKHggPSAiIiwgeSA9ICJEZWx0YSBUZW1wIChDKSIpICsKICB5bGltKC0xLCA1KSArCiAgdGhlbWVfY2xhc3NpYygpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpICAjIENlbnRlcmVkIHRpdGxlCnBsb3RfMjAzMAoKIyBDcmVhdGUgYSBncm91cGVkIGJhciBwbG90IHdpdGggZXJyb3IgYmFycyBmb3IgTWVhbiAyMDYwCnBsb3RfMjA2MCA8LSBnZ3Bsb3QoWUY0NV9kZWNhZGFsLCBhZXMoeCA9IFBvbmQsIHkgPSBNZWFuXzIwNjBfMjA2OSkpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgZmlsbCA9ICIjRjQ2RDQzIiwgY29sb3IgPSAiYmxhY2siKSArCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IE1lYW5fMjA2MF8yMDY5IC0gU0RfMjA2MF8yMDY5LCB5bWF4ID0gTWVhbl8yMDYwXzIwNjkgKyBTRF8yMDYwXzIwNjkpLAogICAgICAgICAgICAgICAgd2lkdGggPSAwLjQsICAjIEFkanVzdCB0aGUgd2lkdGggb2YgZXJyb3IgYmFycyBhcyBuZWVkZWQKICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjkpKSArCiAgbGFicyh4ID0gIiIsIHkgPSAiIikgKyAgIyBObyB5LWF4aXMgbGFiZWwKICB5bGltKC0xLCA1KSArCiAgdGhlbWVfY2xhc3NpYygpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpICsgICMgQ2VudGVyZWQgdGl0bGUgCiAgdGhlbWUoYXhpcy50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCksICAjIFJlbW92ZSBZLWF4aXMgdGljayBtYXJrIGxhYmVscwogICAgICAgIGF4aXMudGlja3MueSA9IGVsZW1lbnRfYmxhbmsoKSkgICAjIFJlbW92ZSBZLWF4aXMgdGlja3MKcGxvdF8yMDYwCgojIENyZWF0ZSBhIGdyb3VwZWQgYmFyIHBsb3Qgd2l0aCBlcnJvciBiYXJzIGZvciBNZWFuIDIwOTAKcGxvdF8yMDkwIDwtIGdncGxvdChZRjQ1X2RlY2FkYWwsIGFlcyh4ID0gUG9uZCwgeSA9IE1lYW5fMjA5MF8yMDk5KSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gIiNENzMwMjciLCBjb2xvciA9ICJibGFjayIpICsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gTWVhbl8yMDkwXzIwOTkgLSBTRF8yMDkwXzIwOTksIHltYXggPSBNZWFuXzIwOTBfMjA5OSArIFNEXzIwOTBfMjA5OSksCiAgICAgICAgICAgICAgICB3aWR0aCA9IDAuNCwgICMgQWRqdXN0IHRoZSB3aWR0aCBvZiBlcnJvciBiYXJzIGFzIG5lZWRlZAogICAgICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuOSkpICsKICBsYWJzKHggPSAiIiwgeSA9ICIiKSArICAjIE5vIHktYXhpcyBsYWJlbAogIHlsaW0oLTEsIDUpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpICsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkgKyAgIyBDZW50ZXJlZCB0aXRsZSAKICB0aGVtZShheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwgICMgUmVtb3ZlIFktYXhpcyB0aWNrIG1hcmsgbGFiZWxzCiAgICAgICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpKSAgICMgUmVtb3ZlIFktYXhpcyB0aWNrcwpwbG90XzIwOTAKCiMgQ29tYmluZSBwbG90cyBpbnRvIGEgcGFuZWwgcGxvdApEZWx0YV9ZRjQ1X3Bsb3QgPC0gZ2dhcnJhbmdlKHBsb3RfMjAzMCwgcGxvdF8yMDYwLCBwbG90XzIwOTAsIG5jb2wgPSAzKQoKIyBTYXZlIHRoZSBjb21iaW5lZCBwbG90Cmdnc2F2ZSgiQ29ycl9EZWx0YVlGNDUucG5nIiwgcGxvdCA9IERlbHRhX1lGNDVfcGxvdCwgd2lkdGggPSA4LCBoZWlnaHQgPSAzKQpgYGAKCiMgU3RhdGlzdGljYWwgdGVzdHMgZm9yIGVhY2ggb2YgdGhlc2UgcG9uZHMgZm9yIDIwMzBzLCAyMDYwcywgYW5kIDIwOTBzCgojIyMgMjAzMHMKYGBge3J9CkRlbHRhX1lGNDUKCiMgTG9hZCByZXF1aXJlZCBsaWJyYXJpZXMKbGlicmFyeShkcGx5cikKbGlicmFyeShicm9vbSkKbGlicmFyeSh0aWR5cikKCiMgU3RlcCAxOiBQcmVwYXJlIHRoZSBkYXRhCmRhdGFfbG9uZyA8LSBEZWx0YV9ZRjQ1ICU+JQogIHNlbGVjdChQb25kLCBtYXRjaGVzKCJeZGlmZl8yMDNbMC05XSQiKSkgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAtUG9uZCwgbmFtZXNfdG8gPSAiWWVhciIsIHZhbHVlc190byA9ICJEaWZmZXJlbmNlIikKCmJveHBsb3QoZGF0YV9sb25nJERpZmZlcmVuY2UgfiBkYXRhX2xvbmckUG9uZCkKCiMgU3RlcCAyOiBDb25kdWN0IEFOT1ZBIGJ5IGdyb3VwaW5nIGJ5IFBvbmQKcmVzX1lGNDUgPC0gYW92KERpZmZlcmVuY2UgfiBQb25kLCBkYXRhID0gZGF0YV9sb25nKQpzdW1tYXJ5KHJlc19ZRjQ1KQoKIyBTdGVwIDM6IFR1a2V5IEhTRApwb3N0X3Rlc3RfWUY0NSA8LSBUdWtleUhTRChyZXNfWUY0NSkKcG9zdF90ZXN0X1lGNDUKCmBgYAoKIyMjIDIwNjBzCmBgYHtyfQpEZWx0YV9ZRjQ1CgojIExvYWQgcmVxdWlyZWQgbGlicmFyaWVzCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoYnJvb20pCgojIFN0ZXAgMTogUHJlcGFyZSB0aGUgZGF0YQpkYXRhX2xvbmcgPC0gRGVsdGFfWUY0NSAlPiUKICBzZWxlY3QoUG9uZCwgbWF0Y2hlcygiXmRpZmZfMjA2WzAtOV0kIikpICU+JQogIHBpdm90X2xvbmdlcihjb2xzID0gLVBvbmQsIG5hbWVzX3RvID0gIlllYXIiLCB2YWx1ZXNfdG8gPSAiRGlmZmVyZW5jZSIpCgpib3hwbG90KGRhdGFfbG9uZyREaWZmZXJlbmNlIH4gZGF0YV9sb25nJFBvbmQpCgojIFN0ZXAgMjogQ29uZHVjdCBBTk9WQSBieSBncm91cGluZyBieSBQb25kCnJlc19ZRjQ1IDwtIGFvdihEaWZmZXJlbmNlIH4gUG9uZCwgZGF0YSA9IGRhdGFfbG9uZykKc3VtbWFyeShyZXNfWUY0NSkKCiMgU3RlcCAzOiBUdWtleSBIU0QKcG9zdF90ZXN0X1lGNDUgPC0gVHVrZXlIU0QocmVzX1lGNDUpCnBvc3RfdGVzdF9ZRjQ1CmBgYAoKIyMjIDIwOTBzCmBgYHtyfQpEZWx0YV9ZRjQ1CgojIExvYWQgcmVxdWlyZWQgbGlicmFyaWVzCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoYnJvb20pCgojIFN0ZXAgMTogUHJlcGFyZSB0aGUgZGF0YQpkYXRhX2xvbmcgPC0gRGVsdGFfWUY0NSAlPiUKICBzZWxlY3QoUG9uZCwgbWF0Y2hlcygiXmRpZmZfMjA5WzAtOV0kIikpICU+JQogIHBpdm90X2xvbmdlcihjb2xzID0gLVBvbmQsIG5hbWVzX3RvID0gIlllYXIiLCB2YWx1ZXNfdG8gPSAiRGlmZmVyZW5jZSIpCgpib3hwbG90KGRhdGFfbG9uZyREaWZmZXJlbmNlIH4gZGF0YV9sb25nJFBvbmQpCgojIFN0ZXAgMjogQ29uZHVjdCBBTk9WQSBieSBncm91cGluZyBieSBQb25kCnJlc19ZRjQ1IDwtIGFvdihEaWZmZXJlbmNlIH4gUG9uZCwgZGF0YSA9IGRhdGFfbG9uZykKc3VtbWFyeShyZXNfWUY0NSkKCiMgU3RlcCAzOiBUdWtleSBIU0QKcG9zdF90ZXN0X1lGNDUgPC0gVHVrZXlIU0QocmVzX1lGNDUpCnBvc3RfdGVzdF9ZRjQ1CmBgYAoKIyBNYWtpbmcgcGxvdHMgb2YgZXJyb3IgYnkgc2Vhc29uCgojIyAyMDEyLTIwMjAKYGBge3J9CiMgRXh0cmFjdCB1bmlxdWUgcG9uZCBuYW1lcyBmcm9tIHRoZSBkYXRhZnJhbWUKc2hvcnRfbmFtZXMgPC0gdW5pcXVlKE1vZF9ZRjQ1JHBvbmRfbmFtZSkKCiMgSW5pdGlhbGl6ZSBhbiBlbXB0eSBkYXRhZnJhbWUgdG8gc3RvcmUgbW9udGhseSBtZWFuIHJlc3VsdHMKbW9udGhseV9tZWFucyA8LSBkYXRhLmZyYW1lKFBvbmQgPSBjaGFyYWN0ZXIoKSwgTW9udGggPSBjaGFyYWN0ZXIoKSwgQXZnVGVtcCA9IG51bWVyaWMoKSwgWWVhciA9IG51bWVyaWMoKSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQoKIyBDb252ZXJ0ICd0aW1lJyBjb2x1bW4gdG8gRGF0ZSBjbGFzcwpNb2RfWUY0NSR0aW1lIDwtIGFzLkRhdGUoTW9kX1lGNDUkdGltZSwgZm9ybWF0PSIlWS0lbS0lZCIpCgojIEV4dHJhY3QgeWVhciBhbmQgbW9udGggZnJvbSAndGltZScgY29sdW1uCk1vZF9ZRjQ1JFllYXIgPC0gZm9ybWF0KE1vZF9ZRjQ1JHRpbWUsICIlWSIpCk1vZF9ZRjQ1JE1vbnRoIDwtIGZvcm1hdChNb2RfWUY0NSR0aW1lLCAiJUIiKQoKIyBMb29wIHRocm91Z2ggZWFjaCB1bmlxdWUgcG9uZCBuYW1lCmZvciAoc2hvcnRfbmFtZSBpbiBzaG9ydF9uYW1lcykgewogICMgRmlsdGVyIGRhdGEgZm9yIHRoZSBjdXJyZW50IHBvbmQKICBwb25kX2RhdGEgPC0gc3Vic2V0KE1vZF9ZRjQ1LCBwb25kX25hbWUgPT0gc2hvcnRfbmFtZSkKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIG1vbnRoCiAgZm9yIChtb250aCBpbiBtb250aC5uYW1lKSB7CiAgICAjIEZpbHRlciBkYXRhIGZvciB0aGUgY3VycmVudCBtb250aAogICAgZmlsdGVyZWRfZGF0YSA8LSBzdWJzZXQocG9uZF9kYXRhLCBNb250aCA9PSBtb250aCkKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIG1lYW4gb2YgJ21lZCcgZm9yIHRoZSBjdXJyZW50IG1vbnRoCiAgICBhdmdfbWVkIDwtIG1lYW4oZmlsdGVyZWRfZGF0YSRtZWQsIG5hLnJtID0gVFJVRSkKICAgIAogICAgIyBBcHBlbmQgcmVzdWx0cyB0byBtb250aGx5X21lYW5zIGRhdGFmcmFtZQogICAgbW9udGhseV9tZWFucyA8LSByYmluZChtb250aGx5X21lYW5zLCBkYXRhLmZyYW1lKFBvbmQgPSBzaG9ydF9uYW1lLCBNb250aCA9IG1vbnRoLCBBdmdUZW1wID0gYXZnX21lZCwgWWVhciA9IDIwMjApKQogIH0KfQoKIyBQcmludCB0aGUgbW9udGhseSBtZWFucyBkYXRhZnJhbWUKcHJpbnQobW9udGhseV9tZWFucykKCiMgUGxvdHRpbmcgdGhlIGRhdGEKZ2dwbG90KG1vbnRobHlfbWVhbnMsIGFlcyh4ID0gTW9udGgsIHkgPSBBdmdUZW1wLCBjb2xvciA9IFBvbmQsIGdyb3VwID0gUG9uZCkpICsKICBnZW9tX2xpbmUoKSArCiAgZ2VvbV9wb2ludCgpICsKICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cyA9IG1vbnRoLm5hbWUpICsKICBsYWJzKHRpdGxlID0gIk1vbnRobHkgQXZlcmFnZSBUZW1wZXJhdHVyZXMgZm9yIEVhY2ggUG9uZCIsCiAgICAgICB4ID0gIk1vbnRoIiwKICAgICAgIHkgPSAiQXZlcmFnZSBUZW1wZXJhdHVyZSIsCiAgICAgICBjb2xvciA9ICJQb25kIikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkKYGBgCgojIyAyMDMwLCAyMDYwLCBhbmQgMjA5MApgYGB7cn0KIyBEZWZpbmUgdGhlIGNvcnJlY3Qgb3JkZXIgZm9yIG1vbnRocwptb250aF9vcmRlciA8LSBjKCJKYW51YXJ5IiwgIkZlYnJ1YXJ5IiwgIk1hcmNoIiwgIkFwcmlsIiwgIk1heSIsICJKdW5lIiwgCiAgICAgICAgICAgICAgICAgICJKdWx5IiwgIkF1Z3VzdCIsICJTZXB0ZW1iZXIiLCAiT2N0b2JlciIsICJOb3ZlbWJlciIsICJEZWNlbWJlciIpCgojIFJlY2FsY3VsYXRlIG1vbnRobHkgYXZlcmFnZXMgd2l0aCBjb3JyZWN0IG1vbnRoIG9yZGVyaW5nCmNhbGN1bGF0ZV9tb250aGx5X2F2ZXJhZ2VzIDwtIGZ1bmN0aW9uKGRhdGEsIGRlY2FkZV9zdGFydCwgZGVjYWRlX2VuZCkgewogICMgSW5pdGlhbGl6ZSBlbXB0eSBkYXRhZnJhbWUgdG8gc3RvcmUgbW9udGhseSBhdmVyYWdlcwogIG1vbnRobHlfYXZnX3RhYmxlIDwtIGRhdGEuZnJhbWUoUG9uZCA9IGNoYXJhY3RlcigpLCBNb250aCA9IGZhY3RvcigpLCBBdmdUZW1wID0gbnVtZXJpYygpLCBZZWFyID0gaW50ZWdlcigpLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCB5ZWFyIGluIHRoZSBkZWNhZGUKICBmb3IgKHlyIGluIGRlY2FkZV9zdGFydDpkZWNhZGVfZW5kKSB7CiAgICAjIEZpbHRlciBkYXRhIGZvciB0aGUgY3VycmVudCB5ZWFyCiAgICB5ZWFybHlfZGF0YSA8LSBkYXRhICU+JQogICAgICBmaWx0ZXIoeWVhcih0aW1lKSA9PSB5cikKICAgIAogICAgIyBMb29wIHRocm91Z2ggZWFjaCBwb25kCiAgICBmb3IgKHBvbmRfbmFtZSBpbiB1bmlxdWUoZGF0YSRwb25kX25hbWUpKSB7CiAgICAgIHBvbmRfZGF0YSA8LSB5ZWFybHlfZGF0YSAlPiUKICAgICAgICBmaWx0ZXIocG9uZF9uYW1lID09IHBvbmRfbmFtZSkKICAgICAgCiAgICAgICMgTG9vcCB0aHJvdWdoIGVhY2ggbW9udGgKICAgICAgZm9yIChtb250aCBpbiBtb250aF9vcmRlcikgewogICAgICAgICMgRmlsdGVyIGRhdGEgZm9yIHRoZSBjdXJyZW50IG1vbnRoCiAgICAgICAgbW9udGhseV9kYXRhIDwtIHBvbmRfZGF0YSAlPiUKICAgICAgICAgIGZpbHRlcihmb3JtYXQodGltZSwgIiVCIikgPT0gbW9udGgpCiAgICAgICAgCiAgICAgICAgIyBDYWxjdWxhdGUgdGhlIG1lYW4gb2YgJ21lZCcgZm9yIHRoZSBjdXJyZW50IG1vbnRoCiAgICAgICAgYXZnX3RlbXAgPC0gbWVhbihtb250aGx5X2RhdGEkbWVkLCBuYS5ybSA9IFRSVUUpCiAgICAgICAgCiAgICAgICAgIyBBcHBlbmQgcmVzdWx0cyB0byBtb250aGx5X2F2Z190YWJsZSBkYXRhZnJhbWUKICAgICAgICBtb250aGx5X2F2Z190YWJsZSA8LSByYmluZChtb250aGx5X2F2Z190YWJsZSwgZGF0YS5mcmFtZShQb25kID0gcG9uZF9uYW1lLCBNb250aCA9IGZhY3Rvcihtb250aCwgbGV2ZWxzID0gbW9udGhfb3JkZXIpLCBBdmdUZW1wID0gYXZnX3RlbXAsIFllYXIgPSB5cikpCiAgICAgIH0KICAgIH0KICB9CiAgCiAgcmV0dXJuKG1vbnRobHlfYXZnX3RhYmxlKQp9CgojIENhbGN1bGF0ZSBtb250aGx5IGF2ZXJhZ2VzIGZvciBlYWNoIGRlY2FkZQptb250aGx5X2F2Z1g1MF90YWJsZV8yMDMwcyA8LSBjYWxjdWxhdGVfbW9udGhseV9hdmVyYWdlcyhNb2RfWUY0NSwgMjAzMCwgMjAzOSkKbW9udGhseV9hdmdYNTBfdGFibGVfMjA2MHMgPC0gY2FsY3VsYXRlX21vbnRobHlfYXZlcmFnZXMoTW9kX1lGNDUsIDIwNjAsIDIwNjkpCm1vbnRobHlfYXZnWDUwX3RhYmxlXzIwOTBzIDwtIGNhbGN1bGF0ZV9tb250aGx5X2F2ZXJhZ2VzKE1vZF9ZRjQ1LCAyMDkwLCAyMDk5KQpgYGAKIyBDb21iaW5lIGFsbCB0aGUgbW9udGhseSBhdmVyYWdlIHRhYmxlcyBpbnRvIG9uZSBkYXRhZnJhbWUgCgpgYGB7cn0KIyBBZGQgYSBEZWNhZGUgY29sdW1uIHRvIGVhY2ggZGF0YWZyYW1lCm1vbnRobHlfbWVhbnMgPC0gbW9udGhseV9tZWFucyAlPiUKICBtdXRhdGUoRGVjYWRlID0gIjIwMjBzIikKCm1vbnRobHlfYXZnWDUwX3RhYmxlXzIwMzBzIDwtIG1vbnRobHlfYXZnWDUwX3RhYmxlXzIwMzBzICU+JQogIG11dGF0ZShEZWNhZGUgPSAiMjAzMHMiKQoKbW9udGhseV9hdmdYNTBfdGFibGVfMjA2MHMgPC0gbW9udGhseV9hdmdYNTBfdGFibGVfMjA2MHMgJT4lCiAgbXV0YXRlKERlY2FkZSA9ICIyMDYwcyIpCgptb250aGx5X2F2Z1g1MF90YWJsZV8yMDkwcyA8LSBtb250aGx5X2F2Z1g1MF90YWJsZV8yMDkwcyAlPiUKICBtdXRhdGUoRGVjYWRlID0gIjIwOTBzIikKCiMgQ29tYmluZSBhbGwgbW9udGhseSBhdmVyYWdlIHRhYmxlcyBpbnRvIG9uZSBkYXRhZnJhbWUKY29tYmluZWRfbW9udGhseV9hdmcgPC0gYmluZF9yb3dzKAogIG1vbnRobHlfbWVhbnMsCiAgbW9udGhseV9hdmdYNTBfdGFibGVfMjAzMHMsCiAgbW9udGhseV9hdmdYNTBfdGFibGVfMjA2MHMsCiAgbW9udGhseV9hdmdYNTBfdGFibGVfMjA5MHMKKQoKIyBQcmludCB0aGUgY29tYmluZWQgZGF0YWZyYW1lCnByaW50KGNvbWJpbmVkX21vbnRobHlfYXZnKQpgYGAKCiMgQ2FsY3VsYXRlIHRoZSBkaWZmZXJlbmNlcyBoZXJlIGFzIGNvbXBhcmVkIHRvIDIwMjAKYGBge3J9CiMgRGVmaW5lIHRoZSByZWZlcmVuY2UgeWVhcgpyZWZlcmVuY2VfeWVhciA8LSAyMDIwCgojIENoZWNrIGlmIHRoZSBjb2x1bW4gZXhpc3RzIGFuZCBpcyBjb3JyZWN0bHkgcG9wdWxhdGVkCnN1bW1hcnkoY29tYmluZWRfbW9udGhseV9hdmcpCgojIENhbGN1bGF0ZSBhdmVyYWdlIHRlbXBlcmF0dXJlIGZvciBlYWNoIG1vbnRoIGluIHRoZSByZWZlcmVuY2UgeWVhcgpyZWZfeWVhcl9hdmcgPC0gY29tYmluZWRfbW9udGhseV9hdmcgJT4lCiAgZmlsdGVyKFllYXIgPT0gcmVmZXJlbmNlX3llYXIpICU+JQogIGdyb3VwX2J5KE1vbnRoKSAlPiUKICBzdW1tYXJpc2UoYXZnX3RlbXBfcmVmX3llYXIgPSBtZWFuKEF2Z1RlbXAsIG5hLnJtID0gVFJVRSkpCgojIEpvaW4gcmVmZXJlbmNlIHllYXIgYXZlcmFnZXMgd2l0aCB0aGUgbWFpbiBkYXRhc2V0CmNvbWJpbmVkX21vbnRobHlfYXZnX3dpdGhfZGlmZiA8LSBjb21iaW5lZF9tb250aGx5X2F2ZyAlPiUKICBsZWZ0X2pvaW4ocmVmX3llYXJfYXZnLCBieSA9ICJNb250aCIpICU+JQogIG11dGF0ZShkaWZmX0F2Z1RlbXAgPSBBdmdUZW1wIC0gYXZnX3RlbXBfcmVmX3llYXIpICU+JQogIHNlbGVjdCgtYXZnX3RlbXBfcmVmX3llYXIpICAjIFJlbW92ZSB0aGUgcmVmZXJlbmNlIHllYXIgYXZlcmFnZSBjb2x1bW4KCiMgRGlzcGxheSB0aGUgc3RydWN0dXJlIHRvIHZlcmlmeQpzdHIoY29tYmluZWRfbW9udGhseV9hdmdfd2l0aF9kaWZmKQoKIyBGaWx0ZXIgb3V0IGRhdGEgZm9yIHRoZSByZWZlcmVuY2UgeWVhcgpEZWx0YU1vbnRobHlfWUY0NSA8LSBjb21iaW5lZF9tb250aGx5X2F2Z193aXRoX2RpZmYgJT4lCiAgZmlsdGVyKFllYXIgIT0gcmVmZXJlbmNlX3llYXIpCgojIERpc3BsYXkgdGhlIGZpbHRlcmVkIGRhdGEKcHJpbnQoRGVsdGFNb250aGx5X1lGNDUpCgpgYGAKCgojIENhbGN1bGF0ZSBtZWFuIGRpZmZlcmVuY2VzCgpgYGB7cn0KbGlicmFyeShkcGx5cikKCkRlbHRhTW9udGhseV9ZRjQ1CgpEaWZmTW9udGhseV9ZRjQ1IDwtIERlbHRhTW9udGhseV9ZRjQ1ICU+JQogIHNlbGVjdChQb25kLCBNb250aCwgWWVhciwgZGlmZl9BdmdUZW1wKQoKIyBDcmVhdGUgYSBuZXcgY29sdW1uIGJhc2VkIG9uIHllYXIgcmFuZ2VzCkRpZmZNb250aGx5X1lGNDUkRGVjYWRlIDwtIGlmZWxzZShEaWZmTW9udGhseV9ZRjQ1JFllYXIgPj0gMjAzMCAmIERpZmZNb250aGx5X1lGNDUkWWVhciA8IDIwNDAsICIyMDMwcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKERpZmZNb250aGx5X1lGNDUkWWVhciA+PSAyMDYwICYgRGlmZk1vbnRobHlfWUY0NSRZZWFyIDwgMjA3MCwgIjIwNjBzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoRGlmZk1vbnRobHlfWUY0NSRZZWFyID49IDIwOTAgJiBEaWZmTW9udGhseV9ZRjQ1JFllYXIgPCAyMTAwLCAiMjA5MHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICJPdGhlciIpKSkKCiMgUHJpbnQgdGhlIHVwZGF0ZWQgZGF0YSBmcmFtZQpwcmludChEaWZmTW9udGhseV9ZRjQ1KQogIAojIENvbnZlcnQgTW9udGggdG8gRGF0ZSB0eXBlCkRpZmZNb250aGx5X1lGNDUgPC0gRGlmZk1vbnRobHlfWUY0NSAlPiUKICBtdXRhdGUoTW9udGggPSBhcy5EYXRlKHBhc3RlMChNb250aCwgIiAxICIsIFllYXIpLCBmb3JtYXQgPSAiJUIgJWQgJVkiKSkKCnByaW50KERpZmZNb250aGx5X1lGNDUpCgojIEdyb3VwIGJ5IFBvbmQgYW5kIE1vbnRoLCB0aGVuIGNhbGN1bGF0ZSBtZWFuIGFuZCBzdGFuZGFyZCBkZXZpYXRpb24gb2YgZGlmZl9BdmdUZW1wCnN1bW1hcnlfc3RhdHMgPC0gRGlmZk1vbnRobHlfWUY0NSAlPiUKICBkcGx5cjo6bXV0YXRlKE1vbnRoID0gZm9ybWF0KE1vbnRoLCAiJW0iKSkgJT4lICAjIEV4dHJhY3RzIFlZWVktTU0gZm9ybWF0CiAgZHBseXI6Omdyb3VwX2J5KFBvbmQsIE1vbnRoLCBEZWNhZGUpICU+JQogIGRwbHlyOjpzdW1tYXJpc2UoCiAgICBtZWFuX2RpZmZfQXZnVGVtcCA9IG1lYW4oZGlmZl9BdmdUZW1wLCBuYS5ybSA9IFRSVUUpLAogICAgc2RfZGlmZl9BdmdUZW1wID0gc2QoZGlmZl9BdmdUZW1wLCBuYS5ybSA9IFRSVUUpCiAgKQoKIyBWaWV3IHRoZSBzdW1tYXJ5IHN0YXRpc3RpY3MKcHJpbnQoc3VtbWFyeV9zdGF0cykKCiMgR3JvdXAgYnkganVzdCBNb250aCwgdGhlbiBjYWxjdWxhdGUgbWVhbiBhbmQgc3RhbmRhcmQgZGV2aWF0aW9uIG9mIGRpZmZfQXZnVGVtcApzdW1tYXJ5X3N0YXRzMiA8LSBEaWZmTW9udGhseV9ZRjQ1ICU+JQogIGRwbHlyOjptdXRhdGUoTW9udGggPSBmb3JtYXQoTW9udGgsICIlbSIpKSAlPiUgICMgRXh0cmFjdHMgWVlZWS1NTSBmb3JtYXQKICBkcGx5cjo6Z3JvdXBfYnkoTW9udGgsIERlY2FkZSkgJT4lCiAgZHBseXI6OnN1bW1hcmlzZSgKICAgIG1lYW5fZGlmZl9BdmdUZW1wID0gbWVhbihkaWZmX0F2Z1RlbXAsIG5hLnJtID0gVFJVRSksCiAgICBzZF9kaWZmX0F2Z1RlbXAgPSBzZChkaWZmX0F2Z1RlbXAsIG5hLnJtID0gVFJVRSkKICApCgojIFZpZXcgdGhlIHN1bW1hcnkgc3RhdGlzdGljcwpwcmludChzdW1tYXJ5X3N0YXRzMikKYGBgCgpQbG90dGluZyB0aGUgbW9udGhseSB0ZW1wZXJhdHVyZSBjaGFuZ2UgZ3JhcGhzCgoyMDMwcwpgYGB7cn0Kc3VtbWFyeV9zdGF0cyAjIGdyb3VwZWQgYnkgbW9udGggYW5kIHBvbmQKc3VtbWFyeV9zdGF0czIgIyBncm91cGVkIGJ5IGp1c3QgbW9udGgKCiMgMi4gTW9udGhseSBhdmVyYWdlcyBhY3Jvc3MgcG9uZHMKTW9udGhseVN0YXRzXzIwMzAgPC0gc3VtbWFyeV9zdGF0czIgJT4lCiAgZmlsdGVyKERlY2FkZSA9PSAiMjAzMHMiKSAKCmdncGxvdChkYXRhID0gTW9udGhseVN0YXRzXzIwMzAsIGFlcyh4ID0gTW9udGgpKSArCiAgZ2VvbV9wb2ludChhZXMoeSA9IG1lYW5fZGlmZl9BdmdUZW1wKSkgKwogIHRoZW1lX2NsYXNzaWMoKQoKIyBDb252ZXJ0IE1vbnRoIGZyb20gY2hhcmFjdGVyIHRvIG51bWVyaWMgdG8gZW5zdXJlIHByb3BlciBvcmRlcmluZyBpbiBnZ3Bsb3QKTW9udGhseVN0YXRzXzIwMzAkTW9udGggPC0gYXMubnVtZXJpYyhNb250aGx5U3RhdHNfMjAzMCRNb250aCkKCiMgUGxvdCB1c2luZyBnZ3Bsb3QKTW9udGhseVN0YXRzXzIwMzBQbG90IDwtIGdncGxvdChkYXRhID0gTW9udGhseVN0YXRzXzIwMzAsIGFlcyh4ID0gTW9udGgpKSArCiAgZ2VvbV9saW5lKGFlcyh5ID0gbWVhbl9kaWZmX0F2Z1RlbXApKSArICAjIFBvaW50IHBsb3Qgd2l0aCBtZWFuIHZhbHVlcwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gImRhc2hlZCIsIGNvbG9yID0gImJsYWNrIikgKyAgIyBIb3Jpem9udGFsIGRhc2hlZCBsaW5lIGF0IHkgPSAwCiAgZ2VvbV9yaWJib24oYWVzKHltaW4gPSBtZWFuX2RpZmZfQXZnVGVtcCAtIHNkX2RpZmZfQXZnVGVtcCwgeW1heCA9IG1lYW5fZGlmZl9BdmdUZW1wICsgc2RfZGlmZl9BdmdUZW1wKSwgZmlsbCA9ICJibHVlIiwgYWxwaGEgPSAwLjMpICsgICMgUmliYm9uIGZvciBwb3NpdGl2ZSBhbmQgbmVnYXRpdmUgZXJyb3IgYmFzZWQgb24gc2QgdmFsdWVzCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IDE6MTIsIGxhYmVscyA9IG1vbnRoLmFiYikgKyAgIyBBZGp1c3QgeC1heGlzIGxhYmVscyB0byBzaG93IG1vbnRoIGFiYnJldmlhdGlvbnMKICB5bGltKC00LDYpKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgbGFicyh4ID0gIiIsIHkgPSAiRGVsdGEgVGVtcCAoQykiKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA2NSwgaGp1c3QgPSAxKSkgKwogIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE2KSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSkKTW9udGhseVN0YXRzXzIwMzBQbG90CmBgYAoKMjA2MHMKYGBge3J9CiMgMi4gTW9udGhseSBhdmVyYWdlcyBhY3Jvc3MgcG9uZHMKTW9udGhseVN0YXRzXzIwNjAgPC0gc3VtbWFyeV9zdGF0czIgJT4lCiAgZmlsdGVyKERlY2FkZSA9PSAiMjA2MHMiKSAKCmdncGxvdChkYXRhID0gTW9udGhseVN0YXRzXzIwNjAsIGFlcyh4ID0gTW9udGgpKSArCiAgZ2VvbV9wb2ludChhZXMoeSA9IG1lYW5fZGlmZl9BdmdUZW1wKSkgKwogIHRoZW1lX2NsYXNzaWMoKQoKIyBDb252ZXJ0IE1vbnRoIGZyb20gY2hhcmFjdGVyIHRvIG51bWVyaWMgdG8gZW5zdXJlIHByb3BlciBvcmRlcmluZyBpbiBnZ3Bsb3QKTW9udGhseVN0YXRzXzIwNjAkTW9udGggPC0gYXMubnVtZXJpYyhNb250aGx5U3RhdHNfMjA2MCRNb250aCkKCiMgUGxvdCB1c2luZyBnZ3Bsb3QKTW9udGhseVN0YXRzXzIwNjBQbG90IDwtIGdncGxvdChkYXRhID0gTW9udGhseVN0YXRzXzIwNjAsIGFlcyh4ID0gTW9udGgpKSArCiAgZ2VvbV9saW5lKGFlcyh5ID0gbWVhbl9kaWZmX0F2Z1RlbXApKSArICAjIFBvaW50IHBsb3Qgd2l0aCBtZWFuIHZhbHVlcwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gImRhc2hlZCIsIGNvbG9yID0gImJsYWNrIikgKyAgIyBIb3Jpem9udGFsIGRhc2hlZCBsaW5lIGF0IHkgPSAwCiAgZ2VvbV9yaWJib24oYWVzKHltaW4gPSBtZWFuX2RpZmZfQXZnVGVtcCAtIHNkX2RpZmZfQXZnVGVtcCwgeW1heCA9IG1lYW5fZGlmZl9BdmdUZW1wICsgc2RfZGlmZl9BdmdUZW1wKSwgZmlsbCA9ICJibHVlIiwgYWxwaGEgPSAwLjMpICsgICMgUmliYm9uIGZvciBwb3NpdGl2ZSBhbmQgbmVnYXRpdmUgZXJyb3IgYmFzZWQgb24gc2QgdmFsdWVzCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IDE6MTIsIGxhYmVscyA9IG1vbnRoLmFiYikgKyAgIyBBZGp1c3QgeC1heGlzIGxhYmVscyB0byBzaG93IG1vbnRoIGFiYnJldmlhdGlvbnMKICB5bGltKC00LDYpKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgbGFicyh4ID0gIiIsIHkgPSAiIikgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNjUsIGhqdXN0ID0gMSkpICsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNiksCiAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCkpKwogIHRoZW1lKGF4aXMudGV4dC55ID0gZWxlbWVudF9ibGFuaygpLCAgIyBSZW1vdmUgWS1heGlzIHRpY2sgbWFyayBsYWJlbHMKICAgICAgICBheGlzLnRpY2tzLnkgPSBlbGVtZW50X2JsYW5rKCkpCk1vbnRobHlTdGF0c18yMDYwUGxvdApgYGAKMjA5MHMKYGBge3J9CiMgMi4gTW9udGhseSBhdmVyYWdlcyBhY3Jvc3MgcG9uZHMKTW9udGhseVN0YXRzXzIwOTAgPC0gc3VtbWFyeV9zdGF0czIgJT4lCiAgZmlsdGVyKERlY2FkZSA9PSAiMjA5MHMiKSAKCmdncGxvdChkYXRhID0gTW9udGhseVN0YXRzXzIwOTAsIGFlcyh4ID0gTW9udGgpKSArCiAgZ2VvbV9wb2ludChhZXMoeSA9IG1lYW5fZGlmZl9BdmdUZW1wKSkgKwogIHRoZW1lX2NsYXNzaWMoKQoKIyBDb252ZXJ0IE1vbnRoIGZyb20gY2hhcmFjdGVyIHRvIG51bWVyaWMgdG8gZW5zdXJlIHByb3BlciBvcmRlcmluZyBpbiBnZ3Bsb3QKTW9udGhseVN0YXRzXzIwOTAkTW9udGggPC0gYXMubnVtZXJpYyhNb250aGx5U3RhdHNfMjA5MCRNb250aCkKCiMgUGxvdCB1c2luZyBnZ3Bsb3QKTW9udGhseVN0YXRzXzIwOTBQbG90IDwtIGdncGxvdChkYXRhID0gTW9udGhseVN0YXRzXzIwOTAsIGFlcyh4ID0gTW9udGgpKSArCiAgZ2VvbV9saW5lKGFlcyh5ID0gbWVhbl9kaWZmX0F2Z1RlbXApKSArICAjIFBvaW50IHBsb3Qgd2l0aCBtZWFuIHZhbHVlcwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gImRhc2hlZCIsIGNvbG9yID0gImJsYWNrIikgKyAgIyBIb3Jpem9udGFsIGRhc2hlZCBsaW5lIGF0IHkgPSAwCiAgZ2VvbV9yaWJib24oYWVzKHltaW4gPSBtZWFuX2RpZmZfQXZnVGVtcCAtIHNkX2RpZmZfQXZnVGVtcCwgeW1heCA9IG1lYW5fZGlmZl9BdmdUZW1wICsgc2RfZGlmZl9BdmdUZW1wKSwgZmlsbCA9ICJibHVlIiwgYWxwaGEgPSAwLjMpICsgICMgUmliYm9uIGZvciBwb3NpdGl2ZSBhbmQgbmVnYXRpdmUgZXJyb3IgYmFzZWQgb24gc2QgdmFsdWVzCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IDE6MTIsIGxhYmVscyA9IG1vbnRoLmFiYikgKyAgIyBBZGp1c3QgeC1heGlzIGxhYmVscyB0byBzaG93IG1vbnRoIGFiYnJldmlhdGlvbnMKICB5bGltKC00LDYpKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA2NSwgaGp1c3QgPSAxKSkgKwogIGxhYnMoeCA9ICIiLCB5ID0gIiIpICsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNiksCiAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCkpKwogIHRoZW1lKGF4aXMudGV4dC55ID0gZWxlbWVudF9ibGFuaygpLCAgIyBSZW1vdmUgWS1heGlzIHRpY2sgbWFyayBsYWJlbHMKICAgICAgICBheGlzLnRpY2tzLnkgPSBlbGVtZW50X2JsYW5rKCkpCk1vbnRobHlTdGF0c18yMDkwUGxvdApgYGAKCkNvbWJpbmUgdGhlIHBsb3RzIHRvZ2V0aGVyIGhlcmUgZm9yIG5vdwpgYGB7cn0KIyBDb21iaW5lIHBsb3RzIGludG8gYSBwYW5lbCBwbG90CkRlbHRhTW9udGhfWUY0NV9wbG90IDwtIGdnYXJyYW5nZShNb250aGx5U3RhdHNfMjAzMFBsb3QsIE1vbnRobHlTdGF0c18yMDYwUGxvdCwgTW9udGhseVN0YXRzXzIwOTBQbG90LCBuY29sID0gMykKCiMgU2F2ZSB0aGUgY29tYmluZWQgcGxvdApnZ3NhdmUoIkNvcnJfRGVsdGFNb250aFlGNDUucG5nIiwgcGxvdCA9IERlbHRhTW9udGhfWUY0NV9wbG90LCB3aWR0aCA9IDEyLCBoZWlnaHQgPSAzKQoKYGBgCgpDcmVhdGUgLmNzdiBmaWxlcyBvZiB0aGUgZGF0YSBmb3IgdGhlc2UgZ3JhcGhzCmBgYHtyfQp3cml0ZS5jc3YoTW9udGhseVN0YXRzXzIwMzAsIGZpbGUgPSAiQ29ycl9Nb250aGx5U3RhdHNZRjQ1XzIwMzAuY3N2IikKd3JpdGUuY3N2KE1vbnRobHlTdGF0c18yMDYwLCBmaWxlID0gIkNvcnJfTW9udGhseVN0YXRzWUY0NV8yMDYwLmNzdiIpCndyaXRlLmNzdihNb250aGx5U3RhdHNfMjA5MCwgZmlsZSA9ICJDb3JyX01vbnRobHlTdGF0c1lGNDVfMjA5MC5jc3YiKQpgYGAKCgoKCg==